Setup¶
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
import matplotlib as mpl
from IPython.display import display
from ortools.linear_solver import pywraplp
import time
import logging
import numpy as np
Context¶
Project Description
WoodCraft Creations, a renowned woodcrafting company, is launching a new project to create high-quality wooden tables for homes and offices. Their focus on sustainable sourcing and timeless design ensures each table is both durable and stylish. The new table design requires the following materials:
- Wooden Planks:
Tabletop: 1 plank, providing a smooth, polished surface.Legs: 4 planks, each supporting a leg.Beams: 2 planks, connecting the legs for stability.
- Fasteners:
Screwsor nails to secure the legs, beams, and tabletop. - Reinforcement: Metal
bracketsfor added support at joints. - Adhesive: Wood
glueto reinforce joints and enhance stability.
WoodCraft Creations will develop production and ordering plans based on projected demand. This streamlined approach ensures efficient manufacturing and timely delivery of premium wooden tables.
In this project, WoodCraft Creations will use responsibly sourced materials, carefully selected to maintain environmental standards while delivering high-quality products. From cutting and shaping wood planks to assembling and finishing the tables, the company ensures each step of the production process meets its rigorous quality standards. With an experienced team and a focus on bringing lasting value, this project aims to solidify WoodCraft Creations as a trusted name in the furniture industry. WoodCraft Creations has forecasted the demand for the new table over the next 16 days. They anticipate introducing their tables within the next 5 days.
PART I : Production Planning¶
BOM¶
Table 1: Demand of new Table in the upcoming 16 days¶
| Period | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Demand | 0 | 0 | 0 | 0 | 0 | 18 | 15 | 16 | 12 | 14 | 19 | 10 | 13 | 11 | 17 | 12 |
Table 2: Information regarding production of the new table¶
| Product/material | Table | Tabletop | Leg | Beams | Screws | Planks | Brackets | Glue |
|---|---|---|---|---|---|---|---|---|
| Lead-time | 3 | 2 | 2 | 3 | 1 | 1 | 1 | 1 |
| Initial inventory | 0 | 20 | 100 | 70 | 50 | 100 | 50 | 100 |
| Production cost | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| Inventory cost | 20 | 10 | 10 | 10 | 5 | 5 | 5 | 5 |
| Setup cost | 500 | 200 | 200 | 200 | 200 | 200 | 200 | 200 |
Question 1¶
- Determine the production and ordering plans for the table and its sub-materials. Solve the optimal integrated model and also utilize the decomposition approach. Describe the results, highlighting the differences.
From now on, continue with the optimal method and retain the input of each question for the subsequent ones.
Setting up data and the optimization function¶
def opt_production_plan(data):
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
# Create the mip solver with the SCIP backend.
m = pywraplp.Solver.CreateSolver('SCIP')
logging.debug("Solver created.")
# decision variables
obj = m.NumVar(0, 1000000000, 'obj')
setup = []
production = []
inventory = []
for product in range(len(data.demands)):
setup_temp = []
production_temp = []
inventory_temp = []
for day in range(len(data.days)):
suffix = '_{}_{}'.format(product, day)
setup_temp.append(m.BoolVar('setup' + suffix))
production_temp.append(m.NumVar(0, 100000, 'production' + suffix))
inventory_temp.append(m.NumVar(0, 100000, 'inventory' + suffix))
setup.append(setup_temp)
production.append(production_temp)
inventory.append(inventory_temp)
logging.debug("Variables created.")
# constraints
m.Add(obj >= sum(
sum(production[product]) * data.production_cost[product] +
sum(setup[product]) * data.setup_cost[product] +
sum(inventory[product][:-1] * data.inventory_cost[product])
for product in range(len(data.demands))))
logging.debug("Objective function added.")
# Demand constraint
for product in range(len(data.demands)):
for day in data.days:
# Setup constraint
#logging.debug(f"Adding setup constraint for product {product}, day {day}.")
m.Add(production[product][day] <= 100000 * setup[product][day])
#logging.debug(f"Setup constraint for product {product}, day {day} added.")
if day != 0:
if day - data.lead_time[product] >= 0:
m.Add(inventory[product][day-1] + production[product][day - data.lead_time[product]] == \
(data.demands[product][day] + sum(data.parts[unit][product] * production[unit][day] for unit in range(len(data.demands)))) + inventory[product][day])
else:
m.Add(inventory[product][day-1] == (data.demands[product][day] + sum(data.parts[unit][product] * production[unit][day] for unit in range(len(data.demands)))) + inventory[product][day])
else:
m.Add(data.first_inventory[product] == (data.demands[product][0] + sum(data.parts[unit][product] * production[unit][0] for unit in range(len(data.demands)))) + inventory[product][0])
#logging.debug(f"Demand balance constraint for product {product}, day {day} added.")
logging.debug("All constraints added.")
# objective function
m.Minimize(obj)
logging.debug("Objective function set to minimize.")
# solving the model
status = m.Solve()
logging.debug(f"Solving the model, solver status: {status}")
if status == pywraplp.Solver.OPTIMAL:
PRODUCTION_PLAN = {}
for product in range(len(data.demands)):
PRODUCTION_PLAN_temp = {}
for m_idx, day in enumerate(data.days):
PRODUCTION_PLAN_temp[day] = {
'product ' + str(product): production[product][m_idx].solution_value(), \
'setup': setup[product][m_idx].solution_value(), \
'inventory': inventory[product][m_idx].solution_value()
}
PRODUCTION_PLAN[product] = PRODUCTION_PLAN_temp
logging.debug("Optimal solution found.")
return PRODUCTION_PLAN, obj.solution_value()
elif status == pywraplp.Solver.FEASIBLE:
logging.debug("Solver found a feasible solution, not necessarily optimal.")
elif status == pywraplp.Solver.INFEASIBLE:
logging.debug("Solver found the problem to be infeasible.")
elif status == pywraplp.Solver.UNBOUNDED:
logging.debug("Solver found the problem to be unbounded.")
else:
logging.debug("Solver ended with an unknown status.")
class ProjectData:
def __init__(self):
self.demands = [
[0, 0, 0, 0, 0, 18, 15, 16, 12, 14, 19, 10, 13, 11, 17, 12], # Table demand
[0]*16, # Tabletop demand (calculated)
[0]*16, # Leg demand (calculated)
[0]*16, # Beam demand (calculated)
[0]*16, # Screw demand (calculated)
[0]*16, # Plank demand (calculated)
[0]*16, # Bracket demand (calculated)
[0]*16 # Glue demand (calculated)
]
self.days = range(len(self.demands[0]))
self.parts = [
[0, 1, 4, 2, 0, 0, 0, 0], # Table
[0, 0, 0, 0, 8, 1, 4, 0], # Tabletop
[0, 0, 0, 0, 8, 4, 4, 1], # Leg
[0, 0, 0, 0, 4, 2, 4, 1], # Beam
[0, 0, 0, 0, 0, 0, 0, 0], # Screws
[0, 0, 0, 0, 0, 0, 0, 1], # Plank
[0, 0, 0, 0, 0, 0, 0, 0], # Brackets
[0, 0, 0, 0, 0, 0, 0, 0] # Glue
]
self.lead_time = [3, 2, 2, 3, 1, 1, 1, 1]
self.production_cost = [100] * len(self.demands)
self.first_inventory = [0, 20, 100, 70, 50, 100, 50, 100]
self.inventory_cost = [20, 10, 10, 10, 5, 5, 5, 5]
self.setup_cost = [500, 200, 200, 200, 200, 200, 200, 200]
Using integrated model to find Optimum¶
start_time = time.time()
data = ProjectData()
PRODUCTION_PLAN, obj = opt_production_plan(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-10 04:00:33,421 - DEBUG - Solver created. 2024-06-10 04:00:33,425 - DEBUG - Variables created. 2024-06-10 04:00:33,436 - DEBUG - Objective function added. 2024-06-10 04:00:33,459 - DEBUG - All constraints added. 2024-06-10 04:00:33,462 - DEBUG - Objective function set to minimize. 2024-06-10 04:00:46,780 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:00:46,782 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | -0.0 | 0.0 | 13.0 | 16.0 | 55.0 | 0.0 | 0.0 | 0.0 | 53.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 43.0 | 29.0 | 10.0 | -0.0 | 40.0 | 29.0 | 12.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 55.0 | 0.0 | 0.0 | 0.0 | 53.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 220.0 | 0.0 | 0.0 | 0.0 | 212.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 110.0 | 0.0 | 0.0 | 0.0 | 106.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1073.0 | 2200.0 | 0.0 | 0.0 | 424.0 | 2120.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 489.0 | 935.0 | 0.0 | 0.0 | 212.0 | 901.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 756.0 | 1100.0 | 0.0 | 0.0 | 424.0 | 1060.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 550.0 | 1108.0 | 220.0 | 0.0 | 212.0 | 1007.0 | 212.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
objective is : 1699796 . Run time is : 13.38242506980896
class data_generator_MPS():
def __init__(self):
self.demands = [[0, 0, 0, 0, 0, 18, 15, 16, 12, 14, 19, 10, 13, 11, 17, 12]]
self.days = range(len(self.demands[0]))
self.production_rate = [1]* len(self.days)
self.parts = [[0],
[0],
[0],
[0],
[0],
[0],
[0],
[0]]
self.lead_time = [3]
self.production_cost = [100] * len(self.demands)
self.first_inventory = [0]
self.inventory_cost = [20] * len(self.demands)
self.setup_cost = [500] * len(self.demands)
start_time = time.time()
data = data_generator_MPS()
PRODUCTION_PLAN, obj = opt_production_plan(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-09 14:19:33,196 - DEBUG - Solver created. 2024-06-09 14:19:33,202 - DEBUG - Variables created. 2024-06-09 14:19:33,204 - DEBUG - Objective function added. 2024-06-09 14:19:33,213 - DEBUG - All constraints added. 2024-06-09 14:19:33,213 - DEBUG - Objective function set to minimize. 2024-06-09 14:19:33,276 - DEBUG - Solving the model, solver status: 0 2024-06-09 14:19:33,278 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 0.0 | 0.0 | 33.0 | 0.0 | 28.0 | 0.0 | 14.0 | 29.0 | 0.0 | 24.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 0.0 | 1.0 | 0.0 | 1.0 | 0.0 | 1.0 | 1.0 | 0.0 | 1.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 15.0 | 0.0 | 12.0 | 0.0 | 0.0 | 10.0 | 0.0 | 11.0 | 0.0 | 12.0 | 0.0 |
objective is : 19900 . Run time is : 0.10809922218322754
class data_generator_MRP_tabelT():
def __init__(self):
self.demands = [[0, 0, 33, 0, 28, 0, 14, 29, 0, 24, 0, 29, 0, 0, 0, 0]]
self.days = range(len(self.demands[0]))
self.production_rate = [1]* len(self.days)
self.parts = [[0],
[0],
[0],
[0],
[0],
[0],
[0],
[0]]
self.lead_time = [2]
self.first_inventory = [20]
self.production_cost = [100] * len(self.demands)
self.inventory_cost = [10] * len(self.demands)
self.setup_cost = [200] * len(self.demands)
start_time = time.time()
data = data_generator_MRP_tabelT()
PRODUCTION_PLAN, obj = opt_production_plan(data)
end_time = time.time()
print('Table top obj fct: ')
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-09 14:19:36,571 - DEBUG - Solver created. 2024-06-09 14:19:36,576 - DEBUG - Variables created. 2024-06-09 14:19:36,581 - DEBUG - Objective function added. 2024-06-09 14:19:36,586 - DEBUG - All constraints added. 2024-06-09 14:19:36,587 - DEBUG - Objective function set to minimize. 2024-06-09 14:19:36,600 - DEBUG - Solving the model, solver status: 0 2024-06-09 14:19:36,606 - DEBUG - Optimal solution found.
Table top obj fct:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 13.0 | 0.0 | 28.0 | 0.0 | 14.0 | 29.0 | 0.0 | 24.0 | -0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 1.0 | 0.0 | 1.0 | 1.0 | 0.0 | 1.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
objective is : 15300 . Run time is : 0.055376291275024414
Leg¶
class data_generator_MRP_leg():
def __init__(self):
self.demands = [[0.0, 0.0, 132.0, 0.0, 112.0, 0.0, 56.0, 116.0, 0.0, 96.0, 0.0, 116.0, 0.0, 0.0, 0.0, 0.0]
]
self.days = range(len(self.demands[0]))
self.production_rate = [1]* len(self.days)
self.parts = [[0],
[0],
[0],
[0],
[0],
[0],
[0],
[0]]
self.lead_time = [2]
self.first_inventory = [100]
self.production_cost = [100] * len(self.demands)
self.inventory_cost = [10] * len(self.demands)
self.setup_cost = [200] * len(self.demands)
start_time = time.time()
data = data_generator_MRP_leg()
PRODUCTION_PLAN, obj = opt_production_plan(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-09 14:19:42,188 - DEBUG - Solver created. 2024-06-09 14:19:42,191 - DEBUG - Variables created. 2024-06-09 14:19:42,193 - DEBUG - Objective function added. 2024-06-09 14:19:42,196 - DEBUG - All constraints added. 2024-06-09 14:19:42,198 - DEBUG - Objective function set to minimize. 2024-06-09 14:19:42,202 - DEBUG - Solving the model, solver status: 0 2024-06-09 14:19:42,204 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 32.0 | 0.0 | 112.0 | 0.0 | 56.0 | 116.0 | 0.0 | 96.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 1.0 | 0.0 | 1.0 | 1.0 | 0.0 | 1.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
objective is : 56000 . Run time is : 0.03440499305725098
Beams¶
class data_generator_MRP_beam():
def __init__(self):
self.demands = [[0.0, 0.0, 66.0, 0.0, 56.0, 0.0, 28.0, 58.0, 0.0, 48.0, 0.0, 58.0, 0.0, 0.0, 0.0, 0.0]]
self.days = range(len(self.demands[0]))
self.production_rate = [1]* len(self.days)
self.parts = [[0],
[0],
[0],
[0],
[0],
[0],
[0],
[0]]
self.lead_time = [3]
self.first_inventory = [70]
self.production_cost = [100] * len(self.demands)
self.inventory_cost = [10] * len(self.demands)
self.setup_cost = [200] * len(self.demands)
start_time = time.time()
data = data_generator_MRP_beam()
PRODUCTION_PLAN, obj = opt_production_plan(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-09 14:19:49,043 - DEBUG - Solver created. 2024-06-09 14:19:49,045 - DEBUG - Variables created. 2024-06-09 14:19:49,048 - DEBUG - Objective function added. 2024-06-09 14:19:49,048 - DEBUG - All constraints added. 2024-06-09 14:19:49,048 - DEBUG - Objective function set to minimize. 2024-06-09 14:19:49,057 - DEBUG - Solving the model, solver status: 0 2024-06-09 14:19:49,058 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 0.0 | 52.0 | 0.0 | 28.0 | 58.0 | 0.0 | 48.0 | -0.0 | 58.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 0.0 | 1.0 | 1.0 | 0.0 | 1.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 70.0 | 70.0 | 4.0 | 4.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
objective is : 26880 . Run time is : 0.023196697235107422
Screws¶
# demand for screws for each table_top, legs and beams
list1 = [13.0, 0.0, 28.0, 0.0, 14.0, 29.0, 0.0, 24.0, 0.0, 29.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
list2 = [32.0, 0.0, 112.0, 0.0, 56.0, 116.0, 0.0, 96.0, 0.0, 116.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
list3 = [0.0, 52.0, 0.0, 28.0, 58.0, 0.0, 48.0, 0.0, 58.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# Multiply each list by the specified factor
list1_multiplied = [num * 8 for num in list1]
list2_multiplied = [num * 8 for num in list2]
list3_multiplied = [num * 4 for num in list3]
# Combine the three lists by adding corresponding elements
combined_list = [a + b + c for a, b, c in zip(list1_multiplied, list2_multiplied, list3_multiplied)]
print(f'The demand for screws will be : {combined_list}')
The demand for screws will be : [360.0, 208.0, 1120.0, 112.0, 792.0, 1160.0, 192.0, 960.0, 232.0, 1160.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
class data_generator_MRP_screws():
def __init__(self):
self.demands = [[360, 208, 1120, 112, 792, 1160, 192, 960, 232, 1160, 0, 0, 0, 0, 0, 0]]
self.days = range(len(self.demands[0]))
self.production_rate = [1]* len(self.days)
self.parts = [[0],
[0],
[0],
[0]]
self.lead_time = [1]
self.first_inventory = [50]
self.production_cost = [100] * len(self.demands)
self.inventory_cost = [5] * len(self.demands)
self.setup_cost = [200] * len(self.demands)
start_time = time.time()
data = data_generator_MRP_screws()
PRODUCTION_PLAN, obj = opt_production_plan(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-09 14:19:55,515 - DEBUG - Solver created. 2024-06-09 14:19:55,519 - DEBUG - Variables created. 2024-06-09 14:19:55,519 - DEBUG - Objective function added. 2024-06-09 14:19:55,522 - DEBUG - All constraints added. 2024-06-09 14:19:55,522 - DEBUG - Objective function set to minimize. 2024-06-09 14:19:55,522 - DEBUG - Solving the model, solver status: 2 2024-06-09 14:19:55,528 - DEBUG - Solver found the problem to be infeasible.
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[10], line 23 21 start_time = time.time() 22 data = data_generator_MRP_screws() ---> 23 PRODUCTION_PLAN, obj = opt_production_plan(data) 24 end_time = time.time() 26 run_time = end_time - start_time TypeError: cannot unpack non-iterable NoneType object
We observe that The problem does not have an optimal solution. Because screws will need to start at -1 in order to be ready for the production at day 1.
Plank¶
# demand for screws for each table_top, legs and beams
list1 = [13.0, 0.0, 28.0, 0.0, 14.0, 29.0, 0.0, 24.0, 0.0, 29.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
list2 = [32.0, 0.0, 112.0, 0.0, 56.0, 116.0, 0.0, 96.0, 0.0, 116.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
list3 = [0.0, 52.0, 0.0, 28.0, 58.0, 0.0, 48.0, 0.0, 58.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# Multiply each list by the specified factor
list1_multiplied = [num * 1 for num in list1]
list2_multiplied = [num * 4 for num in list2]
list3_multiplied = [num * 2 for num in list3]
# Combine the three lists by adding corresponding elements
combined_list = [a + b + c for a, b, c in zip(list1_multiplied, list2_multiplied, list3_multiplied)]
print(f'The demand for planks will be : {combined_list}')
The demand for planks will be : [141.0, 104.0, 476.0, 56.0, 354.0, 493.0, 96.0, 408.0, 116.0, 493.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
class data_generator_MRP_planks():
def __init__(self):
self.demands = [[141, 104, 476, 56, 354, 493, 96, 408, 116, 493, 0, 0, 0, 0, 0, 0]]
self.days = range(len(self.demands[0]))
self.production_rate = [1]* len(self.days)
self.parts = [[0],
[0],
[0],
[0],
[0],
[0],
[0],
[0]]
self.lead_time = [1]
self.first_inventory = [100]
self.production_cost = [100] * len(self.demands)
self.inventory_cost = [5] * len(self.demands)
self.setup_cost = [200] * len(self.demands)
start_time = time.time()
data = data_generator_MRP_planks()
PRODUCTION_PLAN, obj = opt_production_plan(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-09 14:20:08,600 - DEBUG - Solver created. 2024-06-09 14:20:08,603 - DEBUG - Variables created. 2024-06-09 14:20:08,605 - DEBUG - Objective function added. 2024-06-09 14:20:08,608 - DEBUG - All constraints added. 2024-06-09 14:20:08,608 - DEBUG - Objective function set to minimize. 2024-06-09 14:20:08,611 - DEBUG - Solving the model, solver status: 2 2024-06-09 14:20:08,611 - DEBUG - Solver found the problem to be infeasible.
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[13], line 27 25 start_time = time.time() 26 data = data_generator_MRP_planks() ---> 27 PRODUCTION_PLAN, obj = opt_production_plan(data) 28 end_time = time.time() 30 run_time = end_time - start_time TypeError: cannot unpack non-iterable NoneType object
We observe the same, as to satisfy the demand for table-top, beam and leg the production for plank should also start at -1 day like for screws
Brackets¶
# demand for screws for each table_top, legs and beams
list1 = [13.0, 0.0, 28.0, 0.0, 14.0, 29.0, 0.0, 24.0, 0.0, 29.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
list2 = [32.0, 0.0, 112.0, 0.0, 56.0, 116.0, 0.0, 96.0, 0.0, 116.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
list3 = [0.0, 52.0, 0.0, 28.0, 58.0, 0.0, 48.0, 0.0, 58.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# Multiply each list by the specified factor
list1_multiplied = [num * 4 for num in list1]
list2_multiplied = [num * 4 for num in list2]
list3_multiplied = [num * 4 for num in list3]
# Combine the three lists by adding corresponding elements
combined_list = [a + b + c for a, b, c in zip(list1_multiplied, list2_multiplied, list3_multiplied)]
print(f'The demand for brackets will be : {combined_list}')
The demand for brackets will be : [180.0, 208.0, 560.0, 112.0, 512.0, 580.0, 192.0, 480.0, 232.0, 580.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
class data_generator_MRP_brackets():
def __init__(self):
self.demands = [[180, 208, 560, 112, 512, 580, 192, 480, 232, 580, 0, 0, 0, 0, 0, 0]]
self.days = range(len(self.demands[0]))
self.production_rate = [1]* len(self.days)
self.parts = [[0],
[0],
[0],
[0],
[0],
[0],
[0],
[0]]
self.lead_time = [1]
self.first_inventory = [50]
self.production_cost = [100] * len(self.demands)
self.inventory_cost = [5] * len(self.demands)
self.setup_cost = [200] * len(self.demands)
start_time = time.time()
data = data_generator_MRP_planks()
PRODUCTION_PLAN, obj = opt_production_plan(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-09 14:20:24,542 - DEBUG - Solver created. 2024-06-09 14:20:24,544 - DEBUG - Variables created. 2024-06-09 14:20:24,546 - DEBUG - Objective function added. 2024-06-09 14:20:24,547 - DEBUG - All constraints added. 2024-06-09 14:20:24,547 - DEBUG - Objective function set to minimize. 2024-06-09 14:20:24,552 - DEBUG - Solving the model, solver status: 2 2024-06-09 14:20:24,552 - DEBUG - Solver found the problem to be infeasible.
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[15], line 27 25 start_time = time.time() 26 data = data_generator_MRP_planks() ---> 27 PRODUCTION_PLAN, obj = opt_production_plan(data) 28 end_time = time.time() 30 run_time = end_time - start_time TypeError: cannot unpack non-iterable NoneType object
same problem
Glue¶
# demand for glue for each leg, plank and beams
list1 = [141.0, 104.0, 476.0, 56.0, 354.0, 493.0, 96.0, 408.0, 116.0, 493.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
list2 = [32.0, 0.0, 112.0, 0.0, 56.0, 116.0, 0.0, 96.0, 0.0, 116.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
list3 = [0.0, 52.0, 0.0, 28.0, 58.0, 0.0, 48.0, 0.0, 58.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
# Multiply each list by the specified factor
list1_multiplied = [num * 1 for num in list1]
list2_multiplied = [num * 1 for num in list2]
list3_multiplied = [num * 1 for num in list3]
# Combine the three lists by adding corresponding elements
combined_list = [a + b + c for a, b, c in zip(list1_multiplied, list2_multiplied, list3_multiplied)]
print(f'The demand for glue will be : {combined_list}')
The demand for glue will be : [173.0, 156.0, 588.0, 84.0, 468.0, 609.0, 144.0, 504.0, 174.0, 609.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
class data_generator_MRP_planks():
def __init__(self):
self.demands = [[173.0, 156.0, 588.0, 84.0, 468.0, 609.0, 144.0, 504.0, 174.0, 609.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]
self.days = range(len(self.demands[0]))
self.production_rate = [1]* len(self.days)
self.parts = [[0],
[0],
[0],
[0],
[0],
[0],
[0],
[0]]
self.lead_time = [1]
self.first_inventory = [100]
self.production_cost = [100] * len(self.demands)
self.inventory_cost = [5] * len(self.demands)
self.setup_cost = [200] * len(self.demands)
start_time = time.time()
data = data_generator_MRP_planks()
PRODUCTION_PLAN, obj = opt_production_plan(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-09 14:20:31,321 - DEBUG - Solver created. 2024-06-09 14:20:31,325 - DEBUG - Variables created. 2024-06-09 14:20:31,329 - DEBUG - Objective function added. 2024-06-09 14:20:31,330 - DEBUG - All constraints added. 2024-06-09 14:20:31,333 - DEBUG - Objective function set to minimize. 2024-06-09 14:20:31,335 - DEBUG - Solving the model, solver status: 2 2024-06-09 14:20:31,336 - DEBUG - Solver found the problem to be infeasible.
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[17], line 27 25 start_time = time.time() 26 data = data_generator_MRP_planks() ---> 27 PRODUCTION_PLAN, obj = opt_production_plan(data) 28 end_time = time.time() 30 run_time = end_time - start_time TypeError: cannot unpack non-iterable NoneType object
The integrated model and the decomposition approach to production planning handle the synchronization of production processes differently, which leads to discrepancies in their results, particularly regarding feasibility and efficiency.
Integrated Model Approach: In the integrated model, the entire production process—right from raw materials to final product assembly—is considered as a single cohesive system. This model effectively coordinates all the sub-processes, ensuring that the timing of raw material acquisition, component production, and final assembly is synchronized across all stages. The solver used in the integrated model calculates the optimal production start times for each component, ensuring that all parts are available precisely when needed for assembly, despite the lead times. This is why the integrated model output seems feasible and presents a coherent production plan.
Decomposition Approach: On the other hand, the decomposition approach breaks down the overall production process into smaller, independent units, each optimized separately. While this approach can simplify calculations and potentially increase focus on specific areas or units, it leads to a significant challenge: it does not inherently account for the interdependencies between different production stages. For instance, when you optimize sub-components like screws or planks separately, the model does not account for their necessary synchronization with the production of other parts like table tops or legs. As such, the decomposition model shows that production needs to start before day 1 to meet the demand by the given lead times, a situation that's obviously not feasible.
In essence, the decomposition approach highlights a critical flaw when it comes to the timing of each sub-component's production, suggesting the initiation of production activities before actual start capability (before day 1). This points out a non-feasible solution under actual production constraints and underscores the importance of the integrated model in handling complex, multi-stage production processes where timing synchronization is crucial. The integrated model, by considering all elements of the production chain simultaneously, ensures that all parts are produced and assembled in the right sequence to meet final product delivery dates effectively.
Bah en gros le integrated problem il prend tout en compte en même temps donc au final tout marche alors que decomposition il divise en sous problèmes et ça simplifie justement c’est sous problèmes et donc les contraintes et au final la solution globale est pas forcément faisable
Question 2¶
Take a closer look at the inventories among materials and describe why they are behaving in this way.
I do not observe antything abnormal, inventory naturally decreases as more items are produced which makes sense
Question 3¶
The company has decided to also sell the beams they produce to other companies. In the table below, you can find the forecasted external demand for beams.
Table 3: External demand for the beams:
| Period | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Demand | 0 | 0 | 0 | 0 | 0 | 5 | 7 | 4 | 6 | 7 | 3 | 6 | 5 | 4 | 7 | 6 |
What are the new production plans? Are they different from the ones produced before? Explain.
start_time = time.time()
data = ProjectData()
data.demands = [
[0, 0, 0, 0, 0, 18, 15, 16, 12, 14, 19, 10, 13, 11, 17, 12], # Table demand
[0]*16, # Tabletop demand
[0]*16, # Leg demand
[0, 0, 0, 0, 0, 5, 7, 4, 6, 7, 3, 6, 5, 4, 7, 6], # Beam demand
[0]*16, # Screw demand
[0]*16, # Plank demand
[0]*16, # Bracket demand
[0]*16 # Glue demand
]
PRODUCTION_PLAN, obj = opt_production_plan(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-10 04:01:04,615 - DEBUG - Solver created. 2024-06-10 04:01:04,617 - DEBUG - Variables created. 2024-06-10 04:01:04,627 - DEBUG - Objective function added. 2024-06-10 04:01:04,645 - DEBUG - All constraints added. 2024-06-10 04:01:04,647 - DEBUG - Objective function set to minimize. 2024-06-10 04:01:20,497 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:01:20,500 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 55.0 | 0.0 | 0.0 | -0.0 | 53.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 43.0 | 29.0 | 10.0 | 0.0 | 40.0 | 29.0 | 12.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 55.0 | 0.0 | 0.0 | -0.0 | 53.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 220.0 | 0.0 | 0.0 | -0.0 | 212.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 132.0 | 0.0 | 0.0 | -0.0 | 113.0 | 31.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 17.0 | 10.0 | 6.0 | 0.0 | 0.0 | 28.0 | 22.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1161.0 | 2200.0 | 0.0 | -0.0 | 452.0 | 2244.0 | -0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 533.0 | 935.0 | 0.0 | -0.0 | 226.0 | 963.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 844.0 | 1100.0 | 0.0 | -0.0 | 452.0 | 1184.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 594.0 | 1130.0 | 220.0 | -0.0 | 226.0 | 1076.0 | 243.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
objective is : 1785186 . Run time is : 15.91237759590149
Well of course it is going to be different as we now have more demand for beams which needs screws, planks, brackets and glue, so the production for those components is of course going to increase..
The overall cost is also logically going to be higher as more production means higher costs.
Question 4¶
Now assume that the production cost varies among products as described in Table 4.
| Product/material | Table | Table-top | Leg | Beam | Screws | Plank | Brackets | Glue |
|---|---|---|---|---|---|---|---|---|
| Demand | 100 | 30 | 40 | 70 | 40 | 60 | 80 | 30 |
start_time = time.time()
data = ProjectData()
data.production_cost = [100, 30, 40, 70, 40, 60, 80, 30]
PRODUCTION_PLAN, obj = opt_production_plan(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-10 04:05:08,826 - DEBUG - Solver created. 2024-06-10 04:05:08,830 - DEBUG - Variables created. 2024-06-10 04:05:08,840 - DEBUG - Objective function added. 2024-06-10 04:05:08,853 - DEBUG - All constraints added. 2024-06-10 04:05:08,855 - DEBUG - Objective function set to minimize. 2024-06-10 04:05:18,765 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:05:18,771 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 55.0 | 0.0 | 0.0 | -0.0 | 53.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 43.0 | 29.0 | 10.0 | 0.0 | 40.0 | 29.0 | 12.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 55.0 | 0.0 | 0.0 | -0.0 | 53.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | -0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 220.0 | 0.0 | 0.0 | -0.0 | 212.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 110.0 | 0.0 | -0.0 | 0.0 | 106.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1073.0 | 2200.0 | 0.0 | 0.0 | 424.0 | 2120.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 489.0 | 935.0 | 0.0 | 0.0 | 212.0 | 901.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 756.0 | 1100.0 | -0.0 | 0.0 | 424.0 | 1060.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 550.0 | 1108.0 | 220.0 | 0.0 | 212.0 | 1007.0 | 212.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
objective is : 867616 . Run time is : 9.97316026687622
exactly the same production plan, just cost decrease a whole lot.. The production plans for question 1 and question 4 are identical because the demand patterns, lead times, and optimization objectives remained unchanged in both scenarios. Despite varying production costs in question 4, the consistency in initial inventory levels, setup costs, and the need to meet demand within specific timeframes drove the same scheduling outcomes. The optimization model's constraints and logic, focused on minimizing total costs and ensuring timely production, led to the same production plan for both questions. However, we observe logically that cost decreases as the production costs decreases as well as per the new data which makes sense.
Question 5¶
WoodCraft Creations usually used the stations of the new table during high-demand periods of another popular product. Because of that, the production cost in that period, for these stations which are related to Table assembly, leg, beams, and tabletop stations, becomes 2 times more than usual. This period starts from day 5 to the end of day 9. The production cost will be as follows:
| Period | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Table | 100 | 100 | 100 | 100 | 200 | 200 | 200 | 200 | 200 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| Table-top | 30 | 30 | 30 | 30 | 60 | 60 | 60 | 60 | 60 | 30 | 30 | 30 | 30 | 30 | 30 | 30 |
| Leg | 40 | 40 | 40 | 40 | 80 | 80 | 80 | 80 | 80 | 40 | 40 | 40 | 40 | 40 | 40 | 40 |
| Beams | 70 | 70 | 70 | 70 | 140 | 140 | 140 | 140 | 140 | 70 | 70 | 70 | 70 | 70 | 70 | 70 |
| Screws | 40 | 40 | 40 | 40 | 40 | 40 | 40 | 40 | 40 | 40 | 40 | 40 | 40 | 40 | 40 | 40 |
| Plank | 60 | 60 | 60 | 60 | 60 | 60 | 60 | 60 | 60 | 60 | 60 | 60 | 60 | 60 | 60 | 60 |
| Brackets | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 |
| Glue | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 | 30 |
How does the production plans and the different components of the costs change based on this new information?
def opt_production_plan_2(data):
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
# Create the mip solver with the SCIP backend.
m = pywraplp.Solver.CreateSolver('SCIP')
logging.debug("Solver created.")
# decision variables
obj = m.NumVar(0, 1000000000, 'obj')
setup = []
production = []
inventory = []
for product in range(len(data.demands)):
setup_temp = []
production_temp = []
inventory_temp = []
for day in range(len(data.days)):
suffix = '_{}_{}'.format(product, day)
setup_temp.append(m.BoolVar('setup' + suffix))
production_temp.append(m.NumVar(0, 100000, 'production' + suffix))
inventory_temp.append(m.NumVar(0, 100000, 'inventory' + suffix))
setup.append(setup_temp)
production.append(production_temp)
inventory.append(inventory_temp)
logging.debug("Variables created.")
# Objective function setup
objective_terms = []
for product in range(len(data.demands)):
for day in range(len(data.days)):
term = production[product][day] * data.production_cost[product][day] \
+ setup[product][day] * data.setup_cost[product] \
+ inventory[product][day] * data.inventory_cost[product]
objective_terms.append(term)
m.Add(obj >= sum(objective_terms))
logging.debug("Objective function added.")
# Demand constraint
for product in range(len(data.demands)):
for day in data.days:
# Setup constraint
#logging.debug(f"Adding setup constraint for product {product}, day {day}.")
m.Add(production[product][day] <= 100000 * setup[product][day])
#logging.debug(f"Setup constraint for product {product}, day {day} added.")
if day != 0:
if day - data.lead_time[product] >= 0:
m.Add(inventory[product][day-1] + production[product][day - data.lead_time[product]] == \
(data.demands[product][day] + sum(data.parts[unit][product] * production[unit][day] for unit in range(len(data.demands)))) + inventory[product][day])
else:
m.Add(inventory[product][day-1] == (data.demands[product][day] + sum(data.parts[unit][product] * production[unit][day] for unit in range(len(data.demands)))) + inventory[product][day])
else:
m.Add(data.first_inventory[product] == (data.demands[product][0] + sum(data.parts[unit][product] * production[unit][0] for unit in range(len(data.demands)))) + inventory[product][0])
#logging.debug(f"Demand balance constraint for product {product}, day {day} added.")
logging.debug("All constraints added.")
# objective function
m.Minimize(obj)
logging.debug("Objective function set to minimize.")
# solving the model
status = m.Solve()
logging.debug(f"Solving the model, solver status: {status}")
if status == pywraplp.Solver.OPTIMAL:
PRODUCTION_PLAN = {}
for product in range(len(data.demands)):
PRODUCTION_PLAN_temp = {}
for m_idx, day in enumerate(data.days):
PRODUCTION_PLAN_temp[day] = {
'product ' + str(product): production[product][m_idx].solution_value(), \
'setup': setup[product][m_idx].solution_value(), \
'inventory': inventory[product][m_idx].solution_value()
}
PRODUCTION_PLAN[product] = PRODUCTION_PLAN_temp
logging.debug("Optimal solution found.")
return PRODUCTION_PLAN, obj.solution_value()
elif status == pywraplp.Solver.FEASIBLE:
logging.debug("Solver found a feasible solution, not necessarily optimal.")
elif status == pywraplp.Solver.INFEASIBLE:
logging.debug("Solver found the problem to be infeasible.")
elif status == pywraplp.Solver.UNBOUNDED:
logging.debug("Solver found the problem to be unbounded.")
else:
logging.debug("Solver ended with an unknown status.")
start_time = time.time()
data = ProjectData()
data.production_cost = [
[100] * 16,
[30] * 16,
[40] * 16,
[70] * 16,
[40] * 16,
[60] * 16,
[80] * 16,
[30] * 16
]
# Updating production costs for high-demand periods
high_demand_start, high_demand_end = 4, 9 # Days 5 to 9 (0-indexed as 4 to 8)
affected_items = [0, 1, 2, 3] # Table, Tabletop, Leg, Beams
print("Production costs before update:", data.production_cost)
for day in range(high_demand_start, high_demand_end):
for item in affected_items:
data.production_cost[item][day] *= 2
print("Production costs after update:", data.production_cost)
PRODUCTION_PLAN, obj = opt_production_plan_2(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-10 04:07:29,827 - DEBUG - Solver created. 2024-06-10 04:07:29,830 - DEBUG - Variables created. 2024-06-10 04:07:29,835 - DEBUG - Objective function added. 2024-06-10 04:07:29,852 - DEBUG - All constraints added. 2024-06-10 04:07:29,871 - DEBUG - Objective function set to minimize.
Production costs before update: [[100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60], [80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]] Production costs after update: [[100, 100, 100, 100, 200, 200, 200, 200, 200, 100, 100, 100, 100, 100, 100, 100], [30, 30, 30, 30, 60, 60, 60, 60, 60, 30, 30, 30, 30, 30, 30, 30], [40, 40, 40, 40, 80, 80, 80, 80, 80, 40, 40, 40, 40, 40, 40, 40], [70, 70, 70, 70, 140, 140, 140, 140, 140, 70, 70, 70, 70, 70, 70, 70], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60], [80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]]
2024-06-10 04:07:30,523 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:07:30,524 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 17.0 | 12.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 12.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 48.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 158.0 | 34.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 24.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | -0.0 | 34.0 | 34.0 | 34.0 | 34.0 | 34.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1265.0 | 3296.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1256.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 585.0 | 1411.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 541.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 948.0 | 1716.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 676.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 646.0 | 1632.0 | 350.0 | 0.0 | 0.0 | 0.0 | 0.0 | 541.0 | 140.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
objective is : 879819 . Run time is : 0.7079730033874512
Question 6¶
How do the production plans change if the inventory cost of the table increases to 100 in the last 5 days? Explain.
def opt_production_plan_3(data):
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
# Create the mip solver with the SCIP backend.
m = pywraplp.Solver.CreateSolver('SCIP')
logging.debug("Solver created.")
# decision variables
obj = m.NumVar(0, 1000000000, 'obj')
setup = []
production = []
inventory = []
for product in range(len(data.demands)):
setup_temp = []
production_temp = []
inventory_temp = []
for day in range(len(data.days)):
suffix = '_{}_{}'.format(product, day)
setup_temp.append(m.BoolVar('setup' + suffix))
production_temp.append(m.NumVar(0, 100000, 'production' + suffix))
inventory_temp.append(m.NumVar(0, 100000, 'inventory' + suffix))
setup.append(setup_temp)
production.append(production_temp)
inventory.append(inventory_temp)
logging.debug("Variables created.")
# Objective function setup
objective_terms = []
for product in range(len(data.demands)):
for day in range(len(data.days)):
term = production[product][day] * data.production_cost[product][day] \
+ setup[product][day] * data.setup_cost[product] \
+ inventory[product][day] * data.inventory_cost[product][day]
objective_terms.append(term)
m.Add(obj >= sum(objective_terms))
logging.debug("Objective function added.")
# Demand constraint
for product in range(len(data.demands)):
for day in data.days:
# Setup constraint
#logging.debug(f"Adding setup constraint for product {product}, day {day}.")
m.Add(production[product][day] <= 100000 * setup[product][day])
#logging.debug(f"Setup constraint for product {product}, day {day} added.")
if day != 0:
if day - data.lead_time[product] >= 0:
m.Add(inventory[product][day-1] + production[product][day - data.lead_time[product]] == \
(data.demands[product][day] + sum(data.parts[unit][product] * production[unit][day] for unit in range(len(data.demands)))) + inventory[product][day])
else:
m.Add(inventory[product][day-1] == (data.demands[product][day] + sum(data.parts[unit][product] * production[unit][day] for unit in range(len(data.demands)))) + inventory[product][day])
else:
m.Add(data.first_inventory[product] == (data.demands[product][0] + sum(data.parts[unit][product] * production[unit][0] for unit in range(len(data.demands)))) + inventory[product][0])
#logging.debug(f"Demand balance constraint for product {product}, day {day} added.")
logging.debug("All constraints added.")
# objective function
m.Minimize(obj)
logging.debug("Objective function set to minimize.")
# solving the model
status = m.Solve()
logging.debug(f"Solving the model, solver status: {status}")
if status == pywraplp.Solver.OPTIMAL:
PRODUCTION_PLAN = {}
for product in range(len(data.demands)):
PRODUCTION_PLAN_temp = {}
for m_idx, day in enumerate(data.days):
PRODUCTION_PLAN_temp[day] = {
'product ' + str(product): production[product][m_idx].solution_value(), \
'setup': setup[product][m_idx].solution_value(), \
'inventory': inventory[product][m_idx].solution_value()
}
PRODUCTION_PLAN[product] = PRODUCTION_PLAN_temp
logging.debug("Optimal solution found.")
return PRODUCTION_PLAN, obj.solution_value()
elif status == pywraplp.Solver.FEASIBLE:
logging.debug("Solver found a feasible solution, not necessarily optimal.")
elif status == pywraplp.Solver.INFEASIBLE:
logging.debug("Solver found the problem to be infeasible.")
elif status == pywraplp.Solver.UNBOUNDED:
logging.debug("Solver found the problem to be unbounded.")
else:
logging.debug("Solver ended with an unknown status.")
class ProjectData:
def __init__(self):
self.demands = [
[0, 0, 0, 0, 0, 18, 15, 16, 12, 14, 19, 10, 13, 11, 17, 12], # Table demand
[0]*16, # Tabletop demand
[0]*16, # Leg demand
[0, 0, 0, 0, 0, 5, 7, 4, 6, 7, 3, 6, 5, 4, 7, 6], # Beam demand
[0]*16, # Screw demand
[0]*16, # Plank demand
[0]*16, # Bracket demand
[0]*16 # Glue demand
]
self.days = range(len(self.demands[0]))
self.parts = [
[0, 1, 4, 2, 0, 0, 0, 0], # Table
[0, 0, 0, 0, 8, 1, 4, 0], # Tabletop
[0, 0, 0, 0, 8, 4, 4, 1], # Leg
[0, 0, 0, 0, 4, 2, 4, 1], # Beam
[0, 0, 0, 0, 0, 0, 0, 0], # Screws
[0, 0, 0, 0, 0, 0, 0, 1], # Plank
[0, 0, 0, 0, 0, 0, 0, 0], # Brackets
[0, 0, 0, 0, 0, 0, 0, 0] # Glue
]
self.lead_time = [3, 2, 2, 3, 1, 1, 1, 1]
self.production_cost = [
[100] * 16,
[30] * 16,
[40] * 16,
[70] * 16,
[40] * 16,
[60] * 16,
[80] * 16,
[30] * 16
]
# Updating production costs for high-demand periods
high_demand_start, high_demand_end = 4, 9 # Days 5 to 9 (0-indexed as 4 to 8)
affected_items = [0, 1, 2, 3] # Table, Tabletop, Leg, Beams
print("Production costs before update:", self.production_cost)
for day in range(high_demand_start, high_demand_end):
for item in affected_items:
self.production_cost[item][day] *= 2
print("Production costs after update:", self.production_cost)
self.first_inventory = [0, 20, 100, 70, 50, 100, 50, 100]
# Initialize inventory costs with last 5 days adjusted for the table
self.inventory_cost = [
[20] * 16,
[10] * 16,
[10] * 16,
[10] * 16,
[5] * 16,
[5] * 16,
[5] * 16,
[5] * 16
]
print(self.inventory_cost)
for day in range(11, 16): # Days 12 to 16 (0-indexed as 11 to 15)
self.inventory_cost[0][day] = 100 # Correctly accessing the first product's cost array
print(self.inventory_cost)
self.setup_cost = [500, 200, 200, 200, 200, 200, 200, 200]
start_time = time.time()
data = ProjectData()
PRODUCTION_PLAN, obj = opt_production_plan_3(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-10 04:24:51,808 - DEBUG - Solver created. 2024-06-10 04:24:51,811 - DEBUG - Variables created.
2024-06-10 04:24:51,815 - DEBUG - Objective function added. 2024-06-10 04:24:51,833 - DEBUG - All constraints added. 2024-06-10 04:24:51,835 - DEBUG - Objective function set to minimize.
Production costs before update: [[100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60], [80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]] Production costs after update: [[100, 100, 100, 100, 200, 200, 200, 200, 200, 100, 100, 100, 100, 100, 100, 100], [30, 30, 30, 30, 60, 60, 60, 60, 60, 30, 30, 30, 30, 30, 30, 30], [40, 40, 40, 40, 80, 80, 80, 80, 80, 40, 40, 40, 40, 40, 40, 40], [70, 70, 70, 70, 140, 140, 140, 140, 140, 70, 70, 70, 70, 70, 70, 70], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60], [80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]] [[20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]] [[20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 100, 100, 100, 100, 100], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]]
2024-06-10 04:24:52,590 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:24:52,592 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | 17.0 | 12.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 12.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 116.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 48.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 67.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 46.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 60.0 | 56.0 | 50.0 | 43.0 | 40.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3428.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 1344.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1477.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 585.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1848.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 764.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1703.0 | 383.0 | 0.0 | 0.0 | -0.0 | -0.0 | 585.0 | 162.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
objective is : 929369 . Run time is : 0.8040363788604736
Compare to the production plan in question one we observe that the cost slightly increase which is normal as the inventory cost increases
We also naturally observe that instead of producing 53 unit of tableat day 9 (which will keep some in the inventory), it tries to produce just what is necessary for the high inventory cost days which makes sense
class ProjectData:
def __init__(self):
self.demands = [
[0, 0, 0, 0, 0, 18, 15, 16, 12, 14, 19, 10, 13, 11, 17, 12], # Table demand
[0]*16, # Tabletop demand
[0]*16, # Leg demand
[0, 0, 0, 0, 0, 5, 7, 4, 6, 7, 3, 6, 5, 4, 7, 6], # Beam demand
[0]*16, # Screw demand
[0]*16, # Plank demand
[0]*16, # Bracket demand
[0]*16 # Glue demand
]
self.days = range(len(self.demands[0]))
self.parts = [
[0, 1, 4, 2, 0, 0, 0, 0], # Table
[0, 0, 0, 0, 8, 1, 4, 0], # Tabletop
[0, 0, 0, 0, 8, 4, 4, 1], # Leg
[0, 0, 0, 0, 4, 2, 4, 1], # Beam
[0, 0, 0, 0, 0, 0, 0, 0], # Screws
[0, 0, 0, 0, 0, 0, 0, 1], # Plank
[0, 0, 0, 0, 0, 0, 0, 0], # Brackets
[0, 0, 0, 0, 0, 0, 0, 0] # Glue
]
self.lead_time = [3, 2, 2, 3, 1, 1, 1, 1]
self.production_cost = [
[100] * 16,
[30] * 16,
[40] * 16,
[70] * 16,
[40] * 16,
[60] * 16,
[80] * 16,
[30] * 16
]
# Updating production costs for high-demand periods
high_demand_start, high_demand_end = 4, 9 # Days 5 to 9 (0-indexed as 4 to 8)
affected_items = [0, 1, 2, 3] # Table, Tabletop, Leg, Beams
print("Production costs before update:", self.production_cost)
for day in range(high_demand_start, high_demand_end):
for item in affected_items:
self.production_cost[item][day] *= 2
print("Production costs after update:", self.production_cost)
self.first_inventory = [0, 20, 100, 70, 50, 100, 50, 100]
# Initialize inventory costs with last 5 days adjusted for the table
self.inventory_cost = [
[20] * 16,
[10] * 16,
[10] * 16,
[10] * 16,
[5] * 16,
[5] * 16,
[5] * 16,
[5] * 16
]
print(self.inventory_cost)
for day in range(11, 16): # Days 12 to 16 (0-indexed as 11 to 15)
self.inventory_cost[0][day] = 100 # Correctly accessing the first product's cost array
self.setup_cost = [10000, 200, 200, 200, 200, 200, 200, 200]
start_time = time.time()
data = ProjectData()
PRODUCTION_PLAN, obj = opt_production_plan_3(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-10 03:46:19,579 - DEBUG - Solver created. 2024-06-10 03:46:19,584 - DEBUG - Variables created. 2024-06-10 03:46:19,587 - DEBUG - Objective function added. 2024-06-10 03:46:19,605 - DEBUG - All constraints added.
2024-06-10 03:46:19,607 - DEBUG - Objective function set to minimize.
Production costs before update: [[100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60], [80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]] Production costs after update: [[100, 100, 100, 100, 200, 200, 200, 200, 200, 100, 100, 100, 100, 100, 100, 100], [30, 30, 30, 30, 60, 60, 60, 60, 60, 30, 30, 30, 30, 30, 30, 30], [40, 40, 40, 40, 80, 80, 80, 80, 80, 40, 40, 40, 40, 40, 40, 40], [70, 70, 70, 70, 140, 140, 140, 140, 140, 70, 70, 70, 70, 70, 70, 70], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60], [80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]] [[20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]]
2024-06-10 03:46:20,679 - DEBUG - Solving the model, solver status: 0 2024-06-10 03:46:20,680 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | -0.0 | 0.0 | 13.0 | 16.0 | 108.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 96.0 | 82.0 | 63.0 | 53.0 | 40.0 | 29.0 | 12.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 108.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 432.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 221.0 | 33.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | -0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 26.0 | 22.0 | 16.0 | 9.0 | 6.0 | -0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1517.0 | 4452.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 88.0 | -0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 711.0 | 1902.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 44.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 1200.0 | 2292.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 88.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 772.0 | 2186.0 | 465.0 | 0.0 | 0.0 | 0.0 | -0.0 | 66.0 | 0.0 | -0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 22.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
objective is : 978119 . Run time is : 1.1183288097381592
We clearly observe that it produces more in one batch. This make sense as the setup increase to 10'000 producing all item in one go is more profitable than having multiple setup cost..
The overall cost is also way higher which makes sense because an increase of 95000 is quite a lot
Varying setup cost between 500 and 10000 by 500 intervals¶
data = ProjectData()
for i in range(500,10000, 500):
start_time = time.time()
print(f'testing setup cost of : {i}')
data.setup_cost[0] = i
PRODUCTION_PLAN, obj = opt_production_plan_3(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-10 04:40:13,157 - DEBUG - Solver created. 2024-06-10 04:40:13,160 - DEBUG - Variables created. 2024-06-10 04:40:13,165 - DEBUG - Objective function added. 2024-06-10 04:40:13,177 - DEBUG - All constraints added. 2024-06-10 04:40:13,179 - DEBUG - Objective function set to minimize.
Production costs before update: [[100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60], [80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]] Production costs after update: [[100, 100, 100, 100, 200, 200, 200, 200, 200, 100, 100, 100, 100, 100, 100, 100], [30, 30, 30, 30, 60, 60, 60, 60, 60, 30, 30, 30, 30, 30, 30, 30], [40, 40, 40, 40, 80, 80, 80, 80, 80, 40, 40, 40, 40, 40, 40, 40], [70, 70, 70, 70, 140, 140, 140, 140, 140, 70, 70, 70, 70, 70, 70, 70], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60], [80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]] [[20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]] [[20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 100, 100, 100, 100, 100], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]] testing setup cost of : 500
2024-06-10 04:40:13,957 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:13,960 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | 17.0 | 12.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 12.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 116.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 48.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 67.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 46.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 60.0 | 56.0 | 50.0 | 43.0 | 40.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3428.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 1344.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1477.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 585.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1848.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 764.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1703.0 | 383.0 | 0.0 | 0.0 | -0.0 | -0.0 | 585.0 | 162.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:14,126 - DEBUG - Solver created. 2024-06-10 04:40:14,129 - DEBUG - Variables created. 2024-06-10 04:40:14,134 - DEBUG - Objective function added. 2024-06-10 04:40:14,154 - DEBUG - All constraints added. 2024-06-10 04:40:14,156 - DEBUG - Objective function set to minimize.
objective is : 929369 . Run time is : 0.8147351741790771 testing setup cost of : 1000
2024-06-10 04:40:14,744 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:14,746 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 17.0 | 12.0 | -0.0 | -0.0 | -0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | -0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 12.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 48.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 67.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 46.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 60.0 | 56.0 | 50.0 | 43.0 | 40.0 | -0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3428.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1344.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1477.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 585.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1848.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 764.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1703.0 | 383.0 | 0.0 | 0.0 | 0.0 | 0.0 | 585.0 | 162.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:14,954 - DEBUG - Solver created. 2024-06-10 04:40:14,972 - DEBUG - Variables created. 2024-06-10 04:40:14,978 - DEBUG - Objective function added. 2024-06-10 04:40:15,013 - DEBUG - All constraints added. 2024-06-10 04:40:15,017 - DEBUG - Objective function set to minimize.
objective is : 932369 . Run time is : 0.6379423141479492 testing setup cost of : 1500
2024-06-10 04:40:15,660 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:15,662 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | -0.0 | -0.0 | -0.0 | 0.0 | 17.0 | 12.0 | -0.0 | -0.0 | -0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 12.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 48.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 67.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 46.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 60.0 | 56.0 | 50.0 | 43.0 | 40.0 | 0.0 | 17.0 | 13.0 | 6.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3428.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1344.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1477.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 585.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1848.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 764.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1703.0 | 383.0 | 0.0 | 0.0 | 0.0 | 0.0 | 585.0 | 162.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:15,852 - DEBUG - Solver created. 2024-06-10 04:40:15,854 - DEBUG - Variables created. 2024-06-10 04:40:15,860 - DEBUG - Objective function added. 2024-06-10 04:40:15,873 - DEBUG - All constraints added. 2024-06-10 04:40:15,876 - DEBUG - Objective function set to minimize.
objective is : 935369 . Run time is : 0.7234206199645996 testing setup cost of : 2000
2024-06-10 04:40:16,403 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:16,405 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | -0.0 | -0.0 | -0.0 | 0.0 | 29.0 | 0.0 | -0.0 | -0.0 | -0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | -0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | -0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1286.0 | 3523.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 596.0 | 1524.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 537.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 969.0 | 1943.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1751.0 | 407.0 | 0.0 | 0.0 | -0.0 | 0.0 | 537.0 | 138.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:16,736 - DEBUG - Solver created. 2024-06-10 04:40:16,739 - DEBUG - Variables created. 2024-06-10 04:40:16,754 - DEBUG - Objective function added. 2024-06-10 04:40:16,772 - DEBUG - All constraints added. 2024-06-10 04:40:16,773 - DEBUG - Objective function set to minimize.
objective is : 938170 . Run time is : 0.5679359436035156 testing setup cost of : 2500
2024-06-10 04:40:17,079 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:17,081 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | -0.0 | 12.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | -0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3524.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1525.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 537.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1944.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1751.0 | 407.0 | 0.0 | 0.0 | 0.0 | -0.0 | 537.0 | 138.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:17,281 - DEBUG - Solver created. 2024-06-10 04:40:17,292 - DEBUG - Variables created. 2024-06-10 04:40:17,298 - DEBUG - Objective function added. 2024-06-10 04:40:17,316 - DEBUG - All constraints added. 2024-06-10 04:40:17,317 - DEBUG - Objective function set to minimize.
objective is : 940669 . Run time is : 0.3580307960510254 testing setup cost of : 3000
2024-06-10 04:40:17,680 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:17,681 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | -0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | -0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | -0.0 | 0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3524.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1525.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 969.0 | 1944.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1751.0 | 407.0 | 0.0 | 0.0 | -0.0 | 0.0 | 537.0 | 138.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:17,929 - DEBUG - Solver created. 2024-06-10 04:40:17,931 - DEBUG - Variables created. 2024-06-10 04:40:17,936 - DEBUG - Objective function added. 2024-06-10 04:40:17,950 - DEBUG - All constraints added. 2024-06-10 04:40:17,951 - DEBUG - Objective function set to minimize.
objective is : 943169 . Run time is : 0.41348862648010254 testing setup cost of : 3500
2024-06-10 04:40:18,331 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:18,334 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | -0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | -0.0 | -0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3524.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1525.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 537.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1944.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1751.0 | 407.0 | 0.0 | 0.0 | -0.0 | 0.0 | 537.0 | 138.0 | -0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:18,508 - DEBUG - Solver created. 2024-06-10 04:40:18,510 - DEBUG - Variables created. 2024-06-10 04:40:18,514 - DEBUG - Objective function added. 2024-06-10 04:40:18,529 - DEBUG - All constraints added. 2024-06-10 04:40:18,530 - DEBUG - Objective function set to minimize.
objective is : 945669 . Run time is : 0.4221839904785156 testing setup cost of : 4000
2024-06-10 04:40:18,822 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:18,824 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | -0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 32.0 | 64.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 422.0 | 1296.0 | 3520.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1525.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 3.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 242.0 | 974.0 | 1942.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1752.0 | 407.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 138.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:19,003 - DEBUG - Solver created. 2024-06-10 04:40:19,006 - DEBUG - Variables created. 2024-06-10 04:40:19,035 - DEBUG - Objective function added. 2024-06-10 04:40:19,052 - DEBUG - All constraints added. 2024-06-10 04:40:19,053 - DEBUG - Objective function set to minimize.
objective is : 948207 . Run time is : 0.3326249122619629 testing setup cost of : 4500
2024-06-10 04:40:19,476 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:19,478 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | -0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | -0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | -0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | -0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3524.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1525.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1944.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1751.0 | 407.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 138.0 | 0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:19,663 - DEBUG - Solver created. 2024-06-10 04:40:19,665 - DEBUG - Variables created. 2024-06-10 04:40:19,670 - DEBUG - Objective function added. 2024-06-10 04:40:19,687 - DEBUG - All constraints added. 2024-06-10 04:40:19,689 - DEBUG - Objective function set to minimize.
objective is : 950669 . Run time is : 0.48978137969970703 testing setup cost of : 5000
2024-06-10 04:40:20,031 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:20,032 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | -0.0 | -0.0 | 13.0 | 17.0 | 78.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 1.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 17.0 | 78.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 32.0 | 67.0 | 313.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 29.0 | 162.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | -0.0 | 0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 428.0 | 1316.0 | 3494.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 608.0 | 1512.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 248.0 | 981.0 | 1929.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 669.0 | 1741.0 | 404.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 138.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:20,314 - DEBUG - Solver created. 2024-06-10 04:40:20,317 - DEBUG - Variables created. 2024-06-10 04:40:20,324 - DEBUG - Objective function added. 2024-06-10 04:40:20,347 - DEBUG - All constraints added. 2024-06-10 04:40:20,349 - DEBUG - Objective function set to minimize.
objective is : 953201 . Run time is : 0.3820021152496338 testing setup cost of : 5500
2024-06-10 04:40:21,029 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:21,031 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3524.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1525.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1944.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1751.0 | 407.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 138.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:21,234 - DEBUG - Solver created. 2024-06-10 04:40:21,236 - DEBUG - Variables created. 2024-06-10 04:40:21,240 - DEBUG - Objective function added. 2024-06-10 04:40:21,258 - DEBUG - All constraints added. 2024-06-10 04:40:21,277 - DEBUG - Objective function set to minimize.
objective is : 955669 . Run time is : 0.7293093204498291 testing setup cost of : 6000
2024-06-10 04:40:21,755 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:21,757 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | -0.0 | 12.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 10.0 | 13.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | -0.0 | 6.0 | 3.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 32.0 | 64.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | -0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | -0.0 | 0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 446.0 | 1268.0 | 3524.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1525.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 254.0 | 960.0 | 1944.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 655.0 | 1752.0 | 407.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 138.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:22,054 - DEBUG - Solver created. 2024-06-10 04:40:22,056 - DEBUG - Variables created. 2024-06-10 04:40:22,063 - DEBUG - Objective function added. 2024-06-10 04:40:22,079 - DEBUG - All constraints added. 2024-06-10 04:40:22,080 - DEBUG - Objective function set to minimize.
objective is : 958216 . Run time is : 0.5382781028747559 testing setup cost of : 6500
2024-06-10 04:40:22,383 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:22,385 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 17.0 | 78.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 1.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 17.0 | 78.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 32.0 | 67.0 | 313.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 30.0 | 162.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | -0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 428.0 | 1316.0 | 3494.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 608.0 | 1512.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 537.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 248.0 | 981.0 | 1929.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 669.0 | 1741.0 | 404.0 | 0.0 | 0.0 | 0.0 | -0.0 | 537.0 | 138.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:22,582 - DEBUG - Solver created. 2024-06-10 04:40:22,584 - DEBUG - Variables created. 2024-06-10 04:40:22,590 - DEBUG - Objective function added. 2024-06-10 04:40:22,607 - DEBUG - All constraints added. 2024-06-10 04:40:22,609 - DEBUG - Objective function set to minimize.
objective is : 960701 . Run time is : 0.34572625160217285 testing setup cost of : 7000
2024-06-10 04:40:22,938 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:22,941 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | -0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3524.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1525.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1944.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1751.0 | 407.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 138.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:23,137 - DEBUG - Solver created. 2024-06-10 04:40:23,139 - DEBUG - Variables created. 2024-06-10 04:40:23,146 - DEBUG - Objective function added. 2024-06-10 04:40:23,161 - DEBUG - All constraints added. 2024-06-10 04:40:23,162 - DEBUG - Objective function set to minimize.
objective is : 963169 . Run time is : 0.37119626998901367 testing setup cost of : 7500
2024-06-10 04:40:23,543 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:23,545 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3524.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1525.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1944.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1751.0 | 407.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 138.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:23,734 - DEBUG - Solver created. 2024-06-10 04:40:23,736 - DEBUG - Variables created. 2024-06-10 04:40:23,740 - DEBUG - Objective function added. 2024-06-10 04:40:23,758 - DEBUG - All constraints added. 2024-06-10 04:40:23,760 - DEBUG - Objective function set to minimize.
objective is : 965669 . Run time is : 0.42131733894348145 testing setup cost of : 8000
2024-06-10 04:40:24,157 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:24,160 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | -0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | -0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | -0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3524.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1525.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1944.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1751.0 | 407.0 | 0.0 | 0.0 | -0.0 | 0.0 | 537.0 | 138.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:24,355 - DEBUG - Solver created. 2024-06-10 04:40:24,356 - DEBUG - Variables created. 2024-06-10 04:40:24,360 - DEBUG - Objective function added. 2024-06-10 04:40:24,373 - DEBUG - All constraints added. 2024-06-10 04:40:24,376 - DEBUG - Objective function set to minimize.
objective is : 968169 . Run time is : 0.4386608600616455 testing setup cost of : 8500
2024-06-10 04:40:24,778 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:24,780 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3524.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1525.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1944.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1751.0 | 407.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 138.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:25,005 - DEBUG - Solver created. 2024-06-10 04:40:25,007 - DEBUG - Variables created. 2024-06-10 04:40:25,013 - DEBUG - Objective function added. 2024-06-10 04:40:25,080 - DEBUG - All constraints added. 2024-06-10 04:40:25,083 - DEBUG - Objective function set to minimize.
objective is : 970669 . Run time is : 0.440234899520874 testing setup cost of : 9000
2024-06-10 04:40:25,397 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:25,400 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 17.0 | 78.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 1.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 12.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 17.0 | 78.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 32.0 | 67.0 | 313.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | -0.0 | 29.0 | 162.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | -0.0 | 0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 428.0 | 1316.0 | 3494.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 608.0 | 1512.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 537.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 249.0 | 980.0 | 1929.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 668.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 669.0 | 1741.0 | 404.0 | 0.0 | -0.0 | 0.0 | 0.0 | 537.0 | 138.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
2024-06-10 04:40:25,577 - DEBUG - Solver created. 2024-06-10 04:40:25,578 - DEBUG - Variables created. 2024-06-10 04:40:25,583 - DEBUG - Objective function added. 2024-06-10 04:40:25,597 - DEBUG - All constraints added. 2024-06-10 04:40:25,598 - DEBUG - Objective function set to minimize.
objective is : 973204 . Run time is : 0.4071664810180664 testing setup cost of : 9500
2024-06-10 04:40:26,051 - DEBUG - Solving the model, solver status: 0 2024-06-10 04:40:26,052 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | -0.0 | 12.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 28.0 | 163.0 | 91.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 22.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 0.0 | 84.0 | 80.0 | 74.0 | 67.0 | 64.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3524.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1248.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1525.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1944.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 668.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1751.0 | 407.0 | 0.0 | 0.0 | 0.0 | 0.0 | 537.0 | 138.0 | 0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
objective is : 975669 . Run time is : 0.4882826805114746
Cost naturally increase as setup cost increase.
Cost naturally increase as setup cost increase. The threshold for a change in the production plan seems to be around 2000 for setup cost where we observe that at day 5 it produces more at once
Then we observe that interestingly around the 5000 it changes very ligthly where day 4 produces 1 unit more which is interesting need to investigate that further, then it doesn't change unitl increasing it to 10000. Otherwise same pattern, as setup cost increase overall cost increases
Question 8¶
The process to produce each of the sub-materials in the BOM is as follows:
- Plank: Cutting station
- Leg: Shaping station - Drilling station
- Beam: Shaping station - Drilling station
- Top: Shaping station - Drilling station
- Table: Assembly station - Sanding station - Finishing station
The information regarding each station is given in Table 6.
| Station | Processing time (min) | Setup time (min) | Available stations | Efficiency |
|---|---|---|---|---|
| Cutting | 1 | - | 4 | 80% |
| Shaping | 1.5 | 30 | 2 | 75% |
| Drilling | 0.9 | 5 | 1 | 90% |
| Assembly | 3 | - | 1 | 95% |
| Sanding | 1.5 | - | 1 | 95% |
| Finishing | 2 | - | 1 | 98% |
Each working day is 8 hours.
Solve the production plan again with the new information (both optimally and using the decomposition approach) and compare the results with those obtained previously. Explain the differences.
class ProjectData:
def __init__(self):
self.demands = [
[0, 0, 0, 0, 0, 18, 15, 16, 12, 14, 19, 10, 13, 11, 17, 12], # Table demand
[0]*16, # Tabletop demand
[0]*16, # Leg demand
[0, 0, 0, 0, 0, 5, 7, 4, 6, 7, 3, 6, 5, 4, 7, 6], # Beam demand
[0]*16, # Screw demand
[0]*16, # Plank demand
[0]*16, # Bracket demand
[0]*16 # Glue demand
]
self.days = range(len(self.demands[0]))
self.parts = [
[0, 1, 4, 2, 0, 0, 0, 0], # Table
[0, 0, 0, 0, 8, 1, 4, 0], # Tabletop
[0, 0, 0, 0, 8, 4, 4, 1], # Leg
[0, 0, 0, 0, 4, 2, 4, 1], # Beam
[0, 0, 0, 0, 0, 0, 0, 0], # Screws
[0, 0, 0, 0, 0, 0, 0, 1], # Plank
[0, 0, 0, 0, 0, 0, 0, 0], # Brackets
[0, 0, 0, 0, 0, 0, 0, 0] # Glue
]
self.lead_time = [3, 2, 2, 3, 1, 1, 1, 1]
self.production_cost = [
[100] * 16,
[30] * 16,
[40] * 16,
[70] * 16,
[40] * 16,
[60] * 16,
[80] * 16,
[30] * 16
]
# Updating production costs for high-demand periods
high_demand_start, high_demand_end = 4, 9 # Days 5 to 9 (0-indexed as 4 to 8)
affected_items = [0, 1, 2, 3] # Table, Tabletop, Leg, Beams
print("Production costs before update:", self.production_cost)
for day in range(high_demand_start, high_demand_end):
for item in affected_items:
self.production_cost[item][day] *= 2
print("Production costs after update:", self.production_cost)
self.first_inventory = [0, 20, 100, 70, 50, 100, 50, 100]
# Initialize inventory costs with last 5 days adjusted for the table
self.inventory_cost = [
[20] * 16,
[10] * 16,
[10] * 16,
[10] * 16,
[5] * 16,
[5] * 16,
[5] * 16,
[5] * 16
]
print(self.inventory_cost)
for day in range(11, 16): # Days 12 to 16 (0-indexed as 11 to 15)
self.inventory_cost[0][day] = 100 # Correctly accessing the first product's cost array
print(self.inventory_cost)
self.setup_cost = [500, 200, 200, 200, 200, 200, 200, 200]
capacity = [6.4 * 60 * 4, 6 * 60 * 2, 7.2 * 60, 7.6 * 60, 7.6 * 60, 7.84 * 60]
self.capacity = [[element] * len(self.days) for element in capacity]
self.production_rate = [[0, 0, 0, 3, 1.5, 2], # Table
[0, 1.5, 0.9, 0, 0, 0], # Tabletop
[0, 1.5, 0.9, 0, 0, 0], # Leg
[0, 1.5, 0.9, 0, 0, 0], # Beam
[0, 0, 0, 0, 0, 0], # Screws
[1, 0, 0, 0, 0, 0], # Plank
[0, 0, 0, 0, 0, 0], # Brackets
[0, 0, 0, 0, 0, 0]] # Glue
self.setup_time = [[0, 0, 0, 0, 0, 0], # Table
[0, 30, 5, 0, 0, 0], # Tabletop
[0, 30, 5, 0, 0, 0], # Leg
[0, 30, 5, 0, 0, 0], # Beam
[0, 0, 0, 0, 0, 0], # Screws
[0, 0, 0, 0, 0, 0], # Plank
[0, 0, 0, 0, 0, 0], # Brackets
[0, 0, 0, 0, 0, 0]] # Glue
self.machines = range(len(self.production_rate[0]))
start_time = time.time()
data = ProjectData()
PRODUCTION_PLAN, obj = opt_production_plan_3(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-10 13:19:31,554 - DEBUG - Solver created. 2024-06-10 13:19:31,557 - DEBUG - Variables created. 2024-06-10 13:19:31,563 - DEBUG - Objective function added. 2024-06-10 13:19:31,583 - DEBUG - All constraints added. 2024-06-10 13:19:31,601 - DEBUG - Objective function set to minimize.
Production costs before update: [[100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60], [80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]] Production costs after update: [[100, 100, 100, 100, 200, 200, 200, 200, 200, 100, 100, 100, 100, 100, 100, 100], [30, 30, 30, 30, 60, 60, 60, 60, 60, 30, 30, 30, 30, 30, 30, 30], [40, 40, 40, 40, 80, 80, 80, 80, 80, 40, 40, 40, 40, 40, 40, 40], [70, 70, 70, 70, 140, 140, 140, 140, 140, 70, 70, 70, 70, 70, 70, 70], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60], [80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]] [[20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]] [[20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 100, 100, 100, 100, 100], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]]
2024-06-10 13:19:32,592 - DEBUG - Solving the model, solver status: 0 2024-06-10 13:19:32,594 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 17.0 | 78.0 | 0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 17.0 | 12.0 | -0.0 | -0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 1.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 17.0 | 78.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 12.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | 0.0 | 32.0 | 67.0 | 313.0 | -0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 116.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 48.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | 0.0 | 29.0 | 200.0 | 29.0 | -0.0 | -0.0 | -0.0 | -0.0 | -0.0 | 46.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | 0.0 | 38.0 | 60.0 | 56.0 | 50.0 | 43.0 | 40.0 | 0.0 | 17.0 | 13.0 | 6.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 428.0 | 1469.0 | 3245.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 1344.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 684.0 | 1388.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 585.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | -0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 248.0 | 1134.0 | 1680.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 764.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 746.0 | 1655.0 | 342.0 | -0.0 | 0.0 | 0.0 | 0.0 | 585.0 | 162.0 | 0.0 | 0.0 | 0.0 | -0.0 | -0.0 | -0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
objective is : 929784 . Run time is : 1.0519251823425293
Question 9¶
def opt_production_plan_3(data):
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
# Create the mip solver with the SCIP backend.
m = pywraplp.Solver.CreateSolver('SCIP')
logging.debug("Solver created.")
# decision variables
obj = m.NumVar(0, 1000000000, 'obj')
setup = []
production = []
inventory = []
for product in range(len(data.demands)):
setup_temp = []
production_temp = []
inventory_temp = []
for day in range(len(data.days)):
suffix = '_{}_{}'.format(product, day)
setup_temp.append(m.BoolVar('setup' + suffix))
production_temp.append(m.NumVar(0, 100000, 'production' + suffix))
inventory_temp.append(m.NumVar(0, 100000, 'inventory' + suffix))
setup.append(setup_temp)
production.append(production_temp)
inventory.append(inventory_temp)
logging.debug("Variables created.")
# Objective function setup
objective_terms = []
for product in range(len(data.demands)):
for day in range(len(data.days)):
term = production[product][day] * data.production_cost[product][day] \
+ setup[product][day] * data.setup_cost[product] \
+ inventory[product][day] * data.inventory_cost[product][day]
objective_terms.append(term)
m.Add(obj >= sum(objective_terms))
logging.debug("Objective function added.")
# Demand constraint
for product in range(len(data.demands)):
for day in data.days:
# Setup constraint
#logging.debug(f"Adding setup constraint for product {product}, day {day}.")
m.Add(production[product][day] <= 100000 * setup[product][day])
#logging.debug(f"Setup constraint for product {product}, day {day} added.")
if day != 0:
if day - data.lead_time[product] >= 0:
m.Add(inventory[product][day-1] + production[product][day - data.lead_time[product]] == \
(data.demands[product][day] + sum(data.parts[unit][product] * production[unit][day] for unit in range(len(data.demands)))) + inventory[product][day])
else:
m.Add(inventory[product][day-1] == (data.demands[product][day] + sum(data.parts[unit][product] * production[unit][day] for unit in range(len(data.demands)))) + inventory[product][day])
else:
m.Add(data.first_inventory[product] == (data.demands[product][0] + sum(data.parts[unit][product] * production[unit][0] for unit in range(len(data.demands)))) + inventory[product][0])
#logging.debug(f"Demand balance constraint for product {product}, day {day} added.")
logging.debug("All constraints added.")
# Capacity constraint
for day in data.days:
for machine in data.machines:
m.Add(sum(data.production_rate[product][machine] * production[product][day] + \
data.setup_time[product][machine] * setup[product][day] \
for product in range(len(data.demands))) <= data.capacity[machine][day])
# objective function
m.Minimize(obj)
logging.debug("Objective function set to minimize.")
# solving the model
status = m.Solve()
logging.debug(f"Solving the model, solver status: {status}")
if status == pywraplp.Solver.OPTIMAL:
PRODUCTION_PLAN = {}
for product in range(len(data.demands)):
PRODUCTION_PLAN_temp = {}
for m_idx, day in enumerate(data.days):
PRODUCTION_PLAN_temp[day] = {
'product ' + str(product): production[product][m_idx].solution_value(), \
'setup': setup[product][m_idx].solution_value(), \
'inventory': inventory[product][m_idx].solution_value()
}
PRODUCTION_PLAN[product] = PRODUCTION_PLAN_temp
logging.debug("Optimal solution found.")
return PRODUCTION_PLAN, obj.solution_value()
elif status == pywraplp.Solver.FEASIBLE:
logging.debug("Solver found a feasible solution, not necessarily optimal.")
elif status == pywraplp.Solver.INFEASIBLE:
logging.debug("Solver found the problem to be infeasible.")
elif status == pywraplp.Solver.UNBOUNDED:
logging.debug("Solver found the problem to be unbounded.")
else:
logging.debug("Solver ended with an unknown status.")
class ProjectData:
def __init__(self):
self.demands = [
[0, 0, 0, 0, 0, 18, 15, 16, 12, 14, 19, 10, 13, 11, 17, 12], # Table demand
[0]*16, # Tabletop demand
[0]*16, # Leg demand
[0, 0, 0, 0, 0, 5, 7, 4, 6, 7, 3, 6, 5, 4, 7, 6], # Beam demand
[0]*16, # Screw demand
[0]*16, # Plank demand
[0]*16, # Bracket demand
[0]*16 # Glue demand
]
self.days = range(len(self.demands[0]))
self.parts = [
[0, 1, 4, 2, 0, 0, 0, 0], # Table
[0, 0, 0, 0, 8, 1, 4, 0], # Tabletop
[0, 0, 0, 0, 8, 4, 4, 1], # Leg
[0, 0, 0, 0, 4, 2, 4, 1], # Beam
[0, 0, 0, 0, 0, 0, 0, 0], # Screws
[0, 0, 0, 0, 0, 0, 0, 1], # Plank
[0, 0, 0, 0, 0, 0, 0, 0], # Brackets
[0, 0, 0, 0, 0, 0, 0, 0] # Glue
]
self.lead_time = [3, 2, 2, 3, 1, 1, 1, 1]
self.production_cost = [
[100] * 16,
[30] * 16,
[40] * 16,
[70] * 16,
[40] * 16,
[60] * 16,
[80] * 16,
[30] * 16
]
# Updating production costs for high-demand periods
high_demand_start, high_demand_end = 4, 9 # Days 5 to 9 (0-indexed as 4 to 8)
affected_items = [0, 1, 2, 3] # Table, Tabletop, Leg, Beams
print("Production costs before update:", self.production_cost)
for day in range(high_demand_start, high_demand_end):
for item in affected_items:
self.production_cost[item][day] *= 2
print("Production costs after update:", self.production_cost)
self.first_inventory = [0, 20, 100, 70, 50, 100, 50, 100]
# Initialize inventory costs with last 5 days adjusted for the table
self.inventory_cost = [
[20] * 16,
[10] * 16,
[10] * 16,
[10] * 16,
[5] * 16,
[5] * 16,
[5] * 16,
[5] * 16
]
print(self.inventory_cost)
for day in range(11, 16): # Days 12 to 16 (0-indexed as 11 to 15)
self.inventory_cost[0][day] = 100 # Correctly accessing the first product's cost array
print(self.inventory_cost)
self.setup_cost = [500, 200, 200, 200, 200, 200, 200, 200]
capacity = [6.4 * 60 * 4, 6 * 60 * 3, 7.2 * 60, 7.6 * 60, 7.6 * 60, 7.84 * 60]
self.capacity = [[element] * len(self.days) for element in capacity]
self.production_rate = [[0, 0, 0, 3, 1.5, 2], # Table
[0, 1.5, 0.9, 0, 0, 0], # Tabletop
[0, 1.5, 0.9, 0, 0, 0], # Leg
[0, 1.5, 0.9, 0, 0, 0], # Beam
[0, 0, 0, 0, 0, 0], # Screws
[1, 0, 0, 0, 0, 0], # Plank
[0, 0, 0, 0, 0, 0], # Brackets
[0, 0, 0, 0, 0, 0]] # Glue
self.setup_time = [[0, 0, 0, 0, 0, 0], # Table
[0, 30, 5, 0, 0, 0], # Tabletop
[0, 30, 5, 0, 0, 0], # Leg
[0, 30, 5, 0, 0, 0], # Beam
[0, 0, 0, 0, 0, 0], # Screws
[0, 0, 0, 0, 0, 0], # Plank
[0, 0, 0, 0, 0, 0], # Brackets
[0, 0, 0, 0, 0, 0]] # Glue
self.machines = range(len(self.production_rate[0]))
start_time = time.time()
data = ProjectData()
PRODUCTION_PLAN, obj = opt_production_plan_3(data)
end_time = time.time()
run_time = end_time - start_time
for product in range(len(data.demands)):
# print(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]))
display(pd.DataFrame.from_dict(PRODUCTION_PLAN[product]).round(0))
print('objective is : ', round(obj), '. Run time is : ', run_time)
2024-06-10 13:18:43,653 - DEBUG - Solver created. 2024-06-10 13:18:43,654 - DEBUG - Variables created. 2024-06-10 13:18:43,658 - DEBUG - Objective function added. 2024-06-10 13:18:43,678 - DEBUG - All constraints added. 2024-06-10 13:18:43,696 - DEBUG - Objective function set to minimize.
Production costs before update: [[100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60], [80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]] Production costs after update: [[100, 100, 100, 100, 200, 200, 200, 200, 200, 100, 100, 100, 100, 100, 100, 100], [30, 30, 30, 30, 60, 60, 60, 60, 60, 30, 30, 30, 30, 30, 30, 30], [40, 40, 40, 40, 80, 80, 80, 80, 80, 40, 40, 40, 40, 40, 40, 40], [70, 70, 70, 70, 140, 140, 140, 140, 140, 70, 70, 70, 70, 70, 70, 70], [40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], [60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60], [80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]] [[20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]] [[20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 100, 100, 100, 100, 100], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]]
2024-06-10 13:18:43,948 - DEBUG - Solving the model, solver status: 0 2024-06-10 13:18:43,950 - DEBUG - Optimal solution found.
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 0 | 20.0 | 0.0 | 0.0 | 13.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 17.0 | 12.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 0.0 | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 2.0 | 0.0 | 0.0 | 67.0 | 53.0 | 34.0 | 24.0 | 11.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 1 | 6.0 | 7.0 | 16.0 | 79.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 29.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 6.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 12.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 2 | -0.0 | 33.0 | 63.0 | 316.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 116.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 20.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 48.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 3 | -0.0 | 28.0 | 163.0 | 67.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 46.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 |
| setup | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 30.0 | 30.0 | 30.0 | 4.0 | -0.0 | -0.0 | 60.0 | 56.0 | 50.0 | 43.0 | 40.0 | 0.0 | 17.0 | 13.0 | 6.0 | -0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 4 | 429.0 | 1285.0 | 3428.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1344.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 5 | 100.0 | 595.0 | 1477.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 585.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 94.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 6 | 246.0 | 968.0 | 1848.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 764.0 | 0.0 | 0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 25.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| product 7 | 656.0 | 1703.0 | 383.0 | 0.0 | 0.0 | 0.0 | 0.0 | 585.0 | 162.0 | 0.0 | -0.0 | -0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| setup | 1.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| inventory | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
objective is : 929369 . Run time is : 0.3199882507324219
PART II : Schedulling¶
In this second phase, we’re focusing on the assembly station, a critical part of our production process. It handles various products, some from earlier stages and others newly added. Our goal is to efficiently manage its 3 machines to ensure smooth operations and meet production 3 demands. To cope with the station’s heavy workload, we’ve extended daily working hours to 10, from 8 am to 6 pm. The list of all the materials that need to be processed on the Assembly station is provided in a file named data project.csv. For this part, if specific methods are not mentioned, please create a mathematical model to answer the questions.
Question 1¶
First, find a schedule that minimizes the maximum duration during which machines are working. This enables WoodCraft Creations to accept more orders from outside. Explain the mathematical objective function you use for this purpose and provide a rationale for your choice. Additionally, explore alternative methods for determining the optimal schedule, if any exist. Assume all tasks are available at the beginning of the planning horizon
data = pd.read_csv('data/data_project_1.csv')
data
| Product | Needed_Time(Hour) | Needed_Time(Minute) | Earliest_Available_Time(Day) | Earliest_Available_Time(Hour) | Earliest_Available_Time(Minute) | Priority | Due_Time(Day) | Due_Time(Hour) | Due_Time(Minute) | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2 | 45 | Tuesday | 16 | 45 | 1 | Wednesday | 10 | 30 |
| 1 | 2 | 1 | 45 | Monday | 15 | 45 | 3 | Wednesday | 12 | 0 |
| 2 | 3 | 2 | 45 | Monday | 17 | 45 | 4 | Thursday | 11 | 45 |
| 3 | 4 | 2 | 0 | Monday | 8 | 30 | 1 | Wednesday | 13 | 45 |
| 4 | 5 | 2 | 30 | Monday | 10 | 30 | 1 | Tuesday | 8 | 30 |
| 5 | 6 | 3 | 15 | Tuesday | 16 | 0 | 2 | Thursday | 17 | 30 |
| 6 | 7 | 1 | 30 | Tuesday | 16 | 30 | 3 | Wednesday | 13 | 30 |
| 7 | 8 | 1 | 15 | Tuesday | 17 | 45 | 1 | Friday | 9 | 45 |
| 8 | 9 | 3 | 0 | Monday | 13 | 30 | 2 | Thursday | 14 | 15 |
| 9 | 10 | 3 | 0 | Monday | 17 | 15 | 1 | Wednesday | 12 | 30 |
| 10 | 11 | 3 | 45 | Tuesday | 15 | 45 | 1 | Thursday | 13 | 30 |
| 11 | 12 | 1 | 15 | Monday | 15 | 45 | 1 | Tuesday | 15 | 0 |
| 12 | 13 | 0 | 45 | Monday | 15 | 30 | 1 | Tuesday | 16 | 45 |
| 13 | 14 | 2 | 15 | Monday | 9 | 30 | 1 | Tuesday | 13 | 30 |
| 14 | 15 | 1 | 0 | Tuesday | 13 | 0 | 3 | Tuesday | 15 | 45 |
| 15 | 16 | 2 | 45 | Tuesday | 17 | 0 | 4 | Friday | 17 | 0 |
| 16 | 17 | 2 | 30 | Monday | 15 | 30 | 4 | Wednesday | 8 | 45 |
def time_to_continuous_minutes(day, hour, minute):
# Maps each day to a start minute in the continuous timeline
days_in_continuous_minutes = {
'Monday': 0,
'Tuesday': 1 * 600,
'Wednesday': 2 * 600,
'Thursday': 3 * 600,
'Friday': 4 * 600
}
# Calculate the start minute for the given day and add the hour and minute offset
return days_in_continuous_minutes[day] + (hour - 8) * 60 + minute
JOBS = {
'1': {'release': 0, 'duration': 2 * 60 + 45, 'due': 0, 'weight': 1},
'2': {'release': 0, 'duration': 1 * 60 + 45, 'due': 0, 'weight': 3},
'3': {'release': 0, 'duration': 2 * 60 + 45, 'due': 0, 'weight': 4},
'4': {'release': 0, 'duration': 2 * 60, 'due': 0, 'weight': 1},
'5': {'release': 0, 'duration': 2 * 60 + 30, 'due': 0, 'weight': 1},
'6': {'release': 0, 'duration': 3 * 60 + 15, 'due': 0, 'weight': 2},
'7': {'release': 0, 'duration': 1 * 60 + 30, 'due': 0, 'weight': 3},
'8': {'release': 0, 'duration': 1 * 60 + 15, 'due': 0, 'weight': 1},
'9': {'release': 0, 'duration': 3 * 60, 'due': 0, 'weight': 2},
'10': {'release': 0, 'duration': 3 * 60, 'due': 0, 'weight': 1},
'11': {'release': 0, 'duration': 3 * 60 + 45, 'due': 0, 'weight': 1},
'12': {'release': 0, 'duration': 1 * 60 + 15, 'due': 0, 'weight': 1},
'13': {'release': 0, 'duration': 45, 'due': 0, 'weight': 1},
'14': {'release': 0, 'duration': 2 * 60 + 15, 'due': 0, 'weight': 1},
'15': {'release': 0, 'duration': 1 * 60, 'due': 0, 'weight': 3},
'16': {'release': 0, 'duration': 2 * 60 + 45, 'due': 0, 'weight': 4},
'17': {'release': 0, 'duration': 2 * 60 + 30, 'due': 0, 'weight': 4},
}
MACHINES = ['A', 'B', 'C']
Explanation of how we will treat the data:
- release: This is the earliest available time converted to minutes. For instance, 16:45 on Tuesday is (16*60 + 45) minutes.
- duration: The needed time converted to minutes.
- due: The due time converted to minutes from the start of the week. For instance, Wednesday at 10:30 is (2460 + 1060 + 30) minutes since Monday 00:00.
- weight: This corresponds to the priority. Each job is labeled from 'A' to 'Q', corresponding to the product numbers 1 to 17.
def gantt(JOBS, SCHEDULE={}):
bw = 0.3
plt.figure(figsize=(12, 0.7*(len(JOBS.keys()))))
idx = 0
for j in sorted(JOBS.keys()):
x = JOBS[j]['release']
y = JOBS[j]['due']
plt.fill_between([x,y],[idx-bw,idx-bw],[idx+bw,idx+bw], color='cyan', alpha=0.6)
if j in SCHEDULE.keys():
x = SCHEDULE[j]['start']
y = SCHEDULE[j]['finish']
plt.fill_between([x,y],[idx-bw,idx-bw],[idx+bw,idx+bw], color='grey', alpha=0.5)
plt.plot([x,y,y,x,x], [idx-bw,idx-bw,idx+bw,idx+bw,idx-bw],color='k')
plt.text((SCHEDULE[j]['start'] + SCHEDULE[j]['finish'])/2.0,idx,
'Job ' + j, color='purple', weight='bold',
horizontalalignment='center', verticalalignment='center')
idx += 1
plt.ylim(-0.5, idx-0.5)
plt.title('Job Schedule')
plt.xlabel('Time')
plt.ylabel('Jobs')
plt.yticks(range(len(JOBS)), JOBS.keys())
plt.grid()
xlim = plt.xlim()
if SCHEDULE:
for j in SCHEDULE.keys():
if 'machine' not in SCHEDULE[j].keys():
SCHEDULE[j]['machine'] = 1
MACHINES = sorted(set([SCHEDULE[j]['machine'] for j in SCHEDULE.keys()]))
plt.figure(figsize=(12, 0.7*len(MACHINES)))
for j in sorted(SCHEDULE.keys()):
idx = MACHINES.index(SCHEDULE[j]['machine'])
x = SCHEDULE[j]['start']
y = SCHEDULE[j]['finish']
plt.fill_between([x,y],[idx-bw,idx-bw],[idx+bw,idx+bw], color='grey', alpha=0.5)
plt.plot([x,y,y,x,x], [idx-bw,idx-bw,idx+bw,idx+bw,idx-bw],color='k')
plt.text((SCHEDULE[j]['start'] + SCHEDULE[j]['finish'])/2.0,idx,
'Job ' + j, color='purple', weight='bold',
horizontalalignment='center', verticalalignment='center', rotation=30)
plt.xlim(xlim)
plt.ylim(-0.5, len(MACHINES)-0.5)
plt.title('Machine Schedule')
plt.yticks(range(len(MACHINES)), MACHINES)
plt.ylabel('Machines')
plt.grid()
def kpi(JOBS, SCHEDULE):
KPI = {}
KPI['Makespan'] = max(SCHEDULE[job]['finish'] for job in SCHEDULE)
KPI['Max Pastdue'] = max(max(0, SCHEDULE[job]['finish'] - JOBS[job]['due']) for job in SCHEDULE)
KPI['Sum of Pastdue'] = sum(max(0, SCHEDULE[job]['finish'] - JOBS[job]['due']) for job in SCHEDULE)
KPI['Number Pastdue'] = sum(SCHEDULE[job]['finish'] > JOBS[job]['due'] for job in SCHEDULE)
KPI['Number on Time'] = sum(SCHEDULE[job]['finish'] <= JOBS[job]['due'] for job in SCHEDULE)
KPI['Fraction on Time'] = KPI['Number on Time']/len(SCHEDULE)
return KPI
def milp(JOBS, MACHINES):
# Create the mip solver with the SCIP backend.
m = pywraplp.Solver.CreateSolver('SCIP')
#Big M
BigM = sum([JOBS[j]['duration'] for j in JOBS.keys()])
# decision variables
completion_time = []
for job_id in JOBS.keys():
suffix = '_%s' % job_id
completion_time.append(m.NumVar(0,BigM,'C' + suffix))
# additional decision variables for use in the objecive
makespan = m.NumVar(0, BigM, 'makespan')
# for binary assignment of jobs to machines
assignJob2Mch = []
for job_id in JOBS.keys():
assignJob2Mch_nested = []
for mch in MACHINES:
# suffix = '_%s_%s' % (job,m)
suffix = '_%s' % job_id
assignJob2Mch_nested.append(m.BoolVar('z' + suffix))
assignJob2Mch.append(assignJob2Mch_nested)
# for modeling disjunctive constraints
auxilaryVar = []
for job in range(len(JOBS.keys())):
auxilaryVar_nested = []
for job_k in JOBS.keys():
auxilaryVar_nested.append(m.BoolVar('y' + suffix))
auxilaryVar.append(auxilaryVar_nested)
# constraints
for mach in range(len(MACHINES)):
m.Add(sum(assignJob2Mch[j][mach]*JOBS[job_id]['duration'] for j,job_id in enumerate(JOBS.keys())) <= makespan)
for j,job_id in enumerate(JOBS.keys()):
m.Add(completion_time[j] <= makespan)
m.Add(completion_time[j] >= JOBS[job_id]['duration'] + JOBS[job_id]['release'])
m.Add(sum(assignJob2Mch[j][mach] for mach in range(len(MACHINES))) == 1)
for k,job_id_k in enumerate(JOBS.keys()):
if k !=j:
for mch in range(len(MACHINES)):
m.Add(completion_time[j] + JOBS[job_id_k]['duration'] <= completion_time[k] + BigM*(auxilaryVar[j][k] + (1-assignJob2Mch[j][mch]) + (1-assignJob2Mch[k][mch])))
m.Add(completion_time[k] + JOBS[job_id]['duration'] <= completion_time[j] + BigM*((1 - auxilaryVar[j][k]) + (1-assignJob2Mch[j][mch]) + (1-assignJob2Mch[k][mch])))
# objective function
m.Minimize(makespan)
status = m.Solve()
# print(m.VerifySolution(0,True))
if status == pywraplp.Solver.OPTIMAL:
SCHEDULE = {}
for j,job_id in enumerate(JOBS.keys()):
mm = [mach for mach in range(len(MACHINES)) if assignJob2Mch[j][mach].solution_value()==1]
SCHEDULE[job_id] = {'machine': MACHINES[mm[0]],
'start': completion_time[j].solution_value() - JOBS[job_id]['duration'],
'finish': completion_time[j].solution_value() }
print(SCHEDULE)
print(m.Objective().Value())
return SCHEDULE
else:
print('The problem does not have an optimal solution.')
def schedule(JOBS, order=sorted(JOBS.keys())):
"""Schedule a dictionary of JOBS on a single machine in a specified order."""
start = 0
finish = 0
SCHEDULE = {}
machine_finish = [0,0,0]
for job in order:
available_machine = machine_finish.index(min(machine_finish))
start = max(JOBS[job]['release'], min(machine_finish))
finish = start + JOBS[job]['duration']
SCHEDULE[job] = {'machine': MACHINES[available_machine],'start': start, 'finish': finish}
machine_finish[available_machine] = finish
return SCHEDULE
MILP¶
SCHEDULE = milp(JOBS, MACHINES)
gantt(JOBS, SCHEDULE)
kpi(JOBS, SCHEDULE)
{'1': {'machine': 'C', 'start': 105.0, 'finish': 270.0}, '2': {'machine': 'C', 'start': 0.0, 'finish': 105.0}, '3': {'machine': 'B', 'start': 180.0, 'finish': 345.0}, '4': {'machine': 'A', 'start': 45.0, 'finish': 165.0}, '5': {'machine': 'A', 'start': 614.9999999999999, 'finish': 764.9999999999999}, '6': {'machine': 'C', 'start': 420.0, 'finish': 615.0}, '7': {'machine': 'A', 'start': 300.0, 'finish': 390.0}, '8': {'machine': 'B', 'start': 510.0, 'finish': 585.0}, '9': {'machine': 'B', 'start': -5.684341886080802e-14, 'finish': 179.99999999999994}, '10': {'machine': 'B', 'start': 584.9999999999999, 'finish': 764.9999999999999}, '11': {'machine': 'A', 'start': 390.0, 'finish': 615.0}, '12': {'machine': 'A', 'start': 165.0, 'finish': 240.0}, '13': {'machine': 'A', 'start': 0.0, 'finish': 45.0}, '14': {'machine': 'C', 'start': 615.0, 'finish': 750.0}, '15': {'machine': 'A', 'start': 240.0, 'finish': 300.0}, '16': {'machine': 'B', 'start': 344.9999999999999, 'finish': 509.9999999999999}, '17': {'machine': 'C', 'start': 270.0, 'finish': 420.0}}
765.0
{'Makespan': 764.9999999999999,
'Max Pastdue': 764.9999999999999,
'Sum of Pastdue': 7065.0,
'Number Pastdue': 17,
'Number on Time': 0,
'Fraction on Time': 0.0}
Optimal schedule
LPT¶
SCHEDULE = schedule(JOBS)
SCHEDULE
order=sorted(JOBS,reverse = True, key=lambda x: (JOBS[x]['duration'], x))
gantt(JOBS, schedule(JOBS,order))
kpi(JOBS, schedule(JOBS,order))
print(sorted(SCHEDULE.keys()))
kpi(JOBS, SCHEDULE)
['1', '10', '11', '12', '13', '14', '15', '16', '17', '2', '3', '4', '5', '6', '7', '8', '9']
{'Makespan': 840,
'Max Pastdue': 840,
'Sum of Pastdue': 7665,
'Number Pastdue': 17,
'Number on Time': 0,
'Fraction on Time': 0.0}
WSPT¶
order=sorted(JOBS,reverse = True, key=lambda x: (JOBS[x]['weight']/JOBS[x]['duration'], x))
print(order)
print([JOBS[x]['weight']/JOBS[x]['duration'] for x in JOBS]) #it prints not in order
gantt(JOBS, schedule(JOBS,order))
kpi(JOBS, schedule(JOBS,order))
['15', '7', '2', '17', '3', '16', '13', '8', '12', '9', '6', '4', '14', '5', '1', '10', '11'] [0.006060606060606061, 0.02857142857142857, 0.024242424242424242, 0.008333333333333333, 0.006666666666666667, 0.010256410256410256, 0.03333333333333333, 0.013333333333333334, 0.011111111111111112, 0.005555555555555556, 0.0044444444444444444, 0.013333333333333334, 0.022222222222222223, 0.007407407407407408, 0.05, 0.024242424242424242, 0.02666666666666667]
{'Makespan': 825,
'Max Pastdue': 825,
'Sum of Pastdue': 6795,
'Number Pastdue': 17,
'Number on Time': 0,
'Fraction on Time': 0.0}
SPT¶
order=sorted(JOBS, key=lambda x: (JOBS[x]['duration'], x))
print(order)
gantt(JOBS, schedule(JOBS,order))
kpi(JOBS, schedule(JOBS,order))
['13', '15', '12', '8', '7', '2', '4', '14', '17', '5', '1', '16', '3', '10', '9', '6', '11']
{'Makespan': 855,
'Max Pastdue': 855,
'Sum of Pastdue': 6285,
'Number Pastdue': 17,
'Number on Time': 0,
'Fraction on Time': 0.0}
Flow time¶
takes too much time to compute..
Table of order based on each rules¶
def print_job_order(JOBS, order):
data = {
'Job': [],
'Start (min)': [],
'Duration (min)': [],
'Due (min)': [],
'Weight': []
}
for job in order:
data['Job'].append(job)
data['Start (min)'].append(JOBS[job]['release'])
data['Duration (min)'].append(JOBS[job]['duration'])
data['Due (min)'].append(JOBS[job]['due'])
data['Weight'].append(JOBS[job]['weight'])
df = pd.DataFrame(data)
display(df)
# LPT - Largest Processing Time first
lpt_order = sorted(JOBS, reverse=True, key=lambda x: (JOBS[x]['duration'], x))
print("LPT Order:")
print_job_order(JOBS, lpt_order)
# WSPT - Weighted Shortest Processing Time first
wspt_order = sorted(JOBS, reverse=True, key=lambda x: (JOBS[x]['weight'] / JOBS[x]['duration'], x))
print("\nWSPT Order:")
print_job_order(JOBS, wspt_order)
# SPT - Shortest Processing Time first
spt_order = sorted(JOBS, key=lambda x: (JOBS[x]['duration'], x))
print("\nSPT Order:")
print_job_order(JOBS, spt_order)
LPT Order:
| Job | Start (min) | Duration (min) | Due (min) | Weight | |
|---|---|---|---|---|---|
| 0 | 11 | 0 | 225 | 0 | 1 |
| 1 | 6 | 0 | 195 | 0 | 2 |
| 2 | 9 | 0 | 180 | 0 | 2 |
| 3 | 10 | 0 | 180 | 0 | 1 |
| 4 | 3 | 0 | 165 | 0 | 4 |
| 5 | 16 | 0 | 165 | 0 | 4 |
| 6 | 1 | 0 | 165 | 0 | 1 |
| 7 | 5 | 0 | 150 | 0 | 1 |
| 8 | 17 | 0 | 150 | 0 | 4 |
| 9 | 14 | 0 | 135 | 0 | 1 |
| 10 | 4 | 0 | 120 | 0 | 1 |
| 11 | 2 | 0 | 105 | 0 | 3 |
| 12 | 7 | 0 | 90 | 0 | 3 |
| 13 | 8 | 0 | 75 | 0 | 1 |
| 14 | 12 | 0 | 75 | 0 | 1 |
| 15 | 15 | 0 | 60 | 0 | 3 |
| 16 | 13 | 0 | 45 | 0 | 1 |
WSPT Order:
| Job | Start (min) | Duration (min) | Due (min) | Weight | |
|---|---|---|---|---|---|
| 0 | 15 | 0 | 60 | 0 | 3 |
| 1 | 7 | 0 | 90 | 0 | 3 |
| 2 | 2 | 0 | 105 | 0 | 3 |
| 3 | 17 | 0 | 150 | 0 | 4 |
| 4 | 3 | 0 | 165 | 0 | 4 |
| 5 | 16 | 0 | 165 | 0 | 4 |
| 6 | 13 | 0 | 45 | 0 | 1 |
| 7 | 8 | 0 | 75 | 0 | 1 |
| 8 | 12 | 0 | 75 | 0 | 1 |
| 9 | 9 | 0 | 180 | 0 | 2 |
| 10 | 6 | 0 | 195 | 0 | 2 |
| 11 | 4 | 0 | 120 | 0 | 1 |
| 12 | 14 | 0 | 135 | 0 | 1 |
| 13 | 5 | 0 | 150 | 0 | 1 |
| 14 | 1 | 0 | 165 | 0 | 1 |
| 15 | 10 | 0 | 180 | 0 | 1 |
| 16 | 11 | 0 | 225 | 0 | 1 |
SPT Order:
| Job | Start (min) | Duration (min) | Due (min) | Weight | |
|---|---|---|---|---|---|
| 0 | 13 | 0 | 45 | 0 | 1 |
| 1 | 15 | 0 | 60 | 0 | 3 |
| 2 | 12 | 0 | 75 | 0 | 1 |
| 3 | 8 | 0 | 75 | 0 | 1 |
| 4 | 7 | 0 | 90 | 0 | 3 |
| 5 | 2 | 0 | 105 | 0 | 3 |
| 6 | 4 | 0 | 120 | 0 | 1 |
| 7 | 14 | 0 | 135 | 0 | 1 |
| 8 | 17 | 0 | 150 | 0 | 4 |
| 9 | 5 | 0 | 150 | 0 | 1 |
| 10 | 1 | 0 | 165 | 0 | 1 |
| 11 | 16 | 0 | 165 | 0 | 4 |
| 12 | 3 | 0 | 165 | 0 | 4 |
| 13 | 10 | 0 | 180 | 0 | 1 |
| 14 | 9 | 0 | 180 | 0 | 2 |
| 15 | 6 | 0 | 195 | 0 | 2 |
| 16 | 11 | 0 | 225 | 0 | 1 |
because based on the course material, the Largest-Processing-Time-first (LPT) heuristic is recommended as the best heuristic method to minimize the duration in scheduling. This method sequences jobs to be processed on a resource in descending order of their processing times. It is particularly effective for minimizing the makespan on identical parallel machines by assigning each job to the machine with the least start time. This approach is illustrated and recommended for its effectiveness in achieving good scheduling performance in minimizing the total processing time Analytics in Operations Management, pages 168-176.
Question 2¶
Now, consider that not all products are ready at the beginning of the scheduling horizon. Assume the release times given in the CSV file and create a new schedule based on the fact that jobs cannot be processed before their release time. Does anything change? How? What is the effect? Describe the characteristics of the new schedule and justify the chosen modeling approach. From now on, keep the release time in your modeling:
JOBS = {
'1': {'release': time_to_continuous_minutes('Tuesday', 16, 45), 'duration': 2 * 60 + 45, 'due': 0, 'weight': 1},
'2': {'release': time_to_continuous_minutes('Monday', 15, 45), 'duration': 1 * 60 + 45, 'due': 0, 'weight': 3},
'3': {'release': time_to_continuous_minutes('Monday', 17, 45), 'duration': 2 * 60 + 45, 'due': 0, 'weight': 4},
'4': {'release': time_to_continuous_minutes('Monday', 8, 30), 'duration': 2 * 60, 'due': 0, 'weight': 1},
'5': {'release': time_to_continuous_minutes('Monday', 10, 30), 'duration': 2 * 60 + 30, 'due': 0, 'weight': 1},
'6': {'release': time_to_continuous_minutes('Tuesday', 16, 0), 'duration': 3 * 60 + 15, 'due': 0, 'weight': 2},
'7': {'release': time_to_continuous_minutes('Tuesday', 16, 30), 'duration': 1 * 60 + 30, 'due': 0, 'weight': 3},
'8': {'release': time_to_continuous_minutes('Tuesday', 17, 45), 'duration': 1 * 60 + 15, 'due': 0, 'weight': 1},
'9': {'release': time_to_continuous_minutes('Monday', 13, 30), 'duration': 3 * 60, 'due': 0, 'weight': 2},
'10': {'release': time_to_continuous_minutes('Monday', 17, 15), 'duration': 3 * 60, 'due': 0, 'weight': 1},
'11': {'release': time_to_continuous_minutes('Tuesday', 15, 45), 'duration': 3 * 60 + 45, 'due': 0, 'weight': 1},
'12': {'release': time_to_continuous_minutes('Monday', 15, 45), 'duration': 1 * 60 + 15, 'due': 0, 'weight': 1},
'13': {'release': time_to_continuous_minutes('Monday', 15, 30), 'duration': 45, 'due': 0, 'weight': 1},
'14': {'release': time_to_continuous_minutes('Monday', 9, 30), 'duration': 2 * 60 + 15, 'due': 0, 'weight': 1},
'15': {'release': time_to_continuous_minutes('Tuesday', 13, 0), 'duration': 1 * 60, 'due': 0, 'weight': 3},
'16': {'release': time_to_continuous_minutes('Tuesday', 17, 0), 'duration': 2 * 60 + 45, 'due': 0, 'weight': 4},
'17': {'release': time_to_continuous_minutes('Monday', 15, 30), 'duration': 2 * 60 + 30, 'due': 0, 'weight': 4},
}
MACHINES = ['A', 'B', 'C']
JOBS
{'1': {'release': 1125, 'duration': 165, 'due': 0, 'weight': 1},
'2': {'release': 465, 'duration': 105, 'due': 0, 'weight': 3},
'3': {'release': 585, 'duration': 165, 'due': 0, 'weight': 4},
'4': {'release': 30, 'duration': 120, 'due': 0, 'weight': 1},
'5': {'release': 150, 'duration': 150, 'due': 0, 'weight': 1},
'6': {'release': 1080, 'duration': 195, 'due': 0, 'weight': 2},
'7': {'release': 1110, 'duration': 90, 'due': 0, 'weight': 3},
'8': {'release': 1185, 'duration': 75, 'due': 0, 'weight': 1},
'9': {'release': 330, 'duration': 180, 'due': 0, 'weight': 2},
'10': {'release': 555, 'duration': 180, 'due': 0, 'weight': 1},
'11': {'release': 1065, 'duration': 225, 'due': 0, 'weight': 1},
'12': {'release': 465, 'duration': 75, 'due': 0, 'weight': 1},
'13': {'release': 450, 'duration': 45, 'due': 0, 'weight': 1},
'14': {'release': 90, 'duration': 135, 'due': 0, 'weight': 1},
'15': {'release': 900, 'duration': 60, 'due': 0, 'weight': 3},
'16': {'release': 1140, 'duration': 165, 'due': 0, 'weight': 4},
'17': {'release': 450, 'duration': 150, 'due': 0, 'weight': 4}}
MILP¶
SCHEDULE = milp(JOBS, MACHINES)
gantt(JOBS, SCHEDULE)
kpi(JOBS, SCHEDULE)
{'1': {'machine': 'C', 'start': 1200.0000000000002, 'finish': 1365.0000000000002}, '2': {'machine': 'A', 'start': 465.0, 'finish': 570.0}, '3': {'machine': 'A', 'start': 585.0, 'finish': 750.0}, '4': {'machine': 'B', 'start': 30.0, 'finish': 150.0}, '5': {'machine': 'A', 'start': 225.00000000000085, 'finish': 375.00000000000085}, '6': {'machine': 'B', 'start': 1080.0, 'finish': 1275.0}, '7': {'machine': 'C', 'start': 1110.0, 'finish': 1200.0}, '8': {'machine': 'A', 'start': 1290.0, 'finish': 1365.0}, '9': {'machine': 'B', 'start': 854.9999999999991, 'finish': 1034.999999999999}, '10': {'machine': 'C', 'start': 555.0, 'finish': 735.0}, '11': {'machine': 'A', 'start': 1065.0, 'finish': 1290.0}, '12': {'machine': 'C', 'start': 465.0, 'finish': 540.0}, '13': {'machine': 'B', 'start': 1034.9999999999998, 'finish': 1079.9999999999998}, '14': {'machine': 'A', 'start': 90.0, 'finish': 225.0}, '15': {'machine': 'A', 'start': 900.0, 'finish': 960.0}, '16': {'machine': 'B', 'start': 1275.0000000000002, 'finish': 1440.0000000000002}, '17': {'machine': 'B', 'start': 450.0, 'finish': 600.0}}
1440.0
{'Makespan': 1440.0000000000002,
'Max Pastdue': 1440.0000000000002,
'Sum of Pastdue': 14955.0,
'Number Pastdue': 17,
'Number on Time': 0,
'Fraction on Time': 0.0}
LPT¶
SCHEDULE = schedule(JOBS)
SCHEDULE
order=sorted(JOBS,reverse = True, key=lambda x: (JOBS[x]['duration'], x))
print("LPT Order:")
print_job_order(JOBS, order)
gantt(JOBS, schedule(JOBS,order))
kpi(JOBS, schedule(JOBS,order))
LPT Order:
| Job | Start (min) | Duration (min) | Due (min) | Weight | |
|---|---|---|---|---|---|
| 0 | 11 | 1065 | 225 | 0 | 1 |
| 1 | 6 | 1080 | 195 | 0 | 2 |
| 2 | 9 | 330 | 180 | 0 | 2 |
| 3 | 10 | 555 | 180 | 0 | 1 |
| 4 | 3 | 585 | 165 | 0 | 4 |
| 5 | 16 | 1140 | 165 | 0 | 4 |
| 6 | 1 | 1125 | 165 | 0 | 1 |
| 7 | 5 | 150 | 150 | 0 | 1 |
| 8 | 17 | 450 | 150 | 0 | 4 |
| 9 | 14 | 90 | 135 | 0 | 1 |
| 10 | 4 | 30 | 120 | 0 | 1 |
| 11 | 2 | 465 | 105 | 0 | 3 |
| 12 | 7 | 1110 | 90 | 0 | 3 |
| 13 | 8 | 1185 | 75 | 0 | 1 |
| 14 | 12 | 465 | 75 | 0 | 1 |
| 15 | 15 | 900 | 60 | 0 | 3 |
| 16 | 13 | 450 | 45 | 0 | 1 |
{'Makespan': 1695,
'Max Pastdue': 1695,
'Sum of Pastdue': 23370,
'Number Pastdue': 17,
'Number on Time': 0,
'Fraction on Time': 0.0}
Question 3¶
3.1¶
There has been an unexpected surge in demand for certain products in the market, prompting the company to prioritize their handling. Could you explain the new objective and schedule requirements?
JOBS = {
'1': {'release': time_to_continuous_minutes('Tuesday', 16, 45), 'duration': 2 * 60 + 45, 'due': time_to_continuous_minutes('Wednesday', 10, 30), 'weight': 1},
'2': {'release': time_to_continuous_minutes('Monday', 15, 45), 'duration': 1 * 60 + 45, 'due': time_to_continuous_minutes('Wednesday', 12, 0), 'weight': 3},
'3': {'release': time_to_continuous_minutes('Monday', 17, 45), 'duration': 2 * 60 + 45, 'due': time_to_continuous_minutes('Thursday', 11, 45), 'weight': 4},
'4': {'release': time_to_continuous_minutes('Monday', 8, 30), 'duration': 2 * 60, 'due': time_to_continuous_minutes('Wednesday', 13, 45), 'weight': 1},
'5': {'release': time_to_continuous_minutes('Monday', 10, 30), 'duration': 2 * 60 + 30, 'due': time_to_continuous_minutes('Tuesday', 8, 30), 'weight': 1},
'6': {'release': time_to_continuous_minutes('Tuesday', 16, 0), 'duration': 3 * 60 + 15, 'due': time_to_continuous_minutes('Thursday', 17, 30), 'weight': 2},
'7': {'release': time_to_continuous_minutes('Tuesday', 16, 30), 'duration': 1 * 60 + 30, 'due': time_to_continuous_minutes('Wednesday', 13, 30), 'weight': 3},
'8': {'release': time_to_continuous_minutes('Tuesday', 17, 45), 'duration': 1 * 60 + 15, 'due': time_to_continuous_minutes('Friday', 9, 45), 'weight': 1},
'9': {'release': time_to_continuous_minutes('Monday', 13, 30), 'duration': 3 * 60, 'due': time_to_continuous_minutes('Thursday', 14, 15), 'weight': 2},
'10': {'release': time_to_continuous_minutes('Monday', 17, 15), 'duration': 3 * 60, 'due': time_to_continuous_minutes('Wednesday', 12, 30), 'weight': 1},
'11': {'release': time_to_continuous_minutes('Tuesday', 15, 45), 'duration': 3 * 60 + 45, 'due': time_to_continuous_minutes('Thursday', 13, 30), 'weight': 1},
'12': {'release': time_to_continuous_minutes('Monday', 15, 45), 'duration': 1 * 60 + 15, 'due': time_to_continuous_minutes('Tuesday', 15, 0), 'weight': 1},
'13': {'release': time_to_continuous_minutes('Monday', 15, 30), 'duration': 45, 'due': time_to_continuous_minutes('Tuesday', 16, 45), 'weight': 1},
'14': {'release': time_to_continuous_minutes('Monday', 9, 30), 'duration': 2 * 60 + 15, 'due': time_to_continuous_minutes('Tuesday', 13, 30), 'weight': 1},
'15': {'release': time_to_continuous_minutes('Tuesday', 13, 0), 'duration': 1 * 60, 'due': time_to_continuous_minutes('Tuesday', 15, 45), 'weight': 3},
'16': {'release': time_to_continuous_minutes('Tuesday', 17, 0), 'duration': 2 * 60 + 45, 'due': time_to_continuous_minutes('Friday', 17, 0), 'weight': 4},
'17': {'release': time_to_continuous_minutes('Monday', 15, 30), 'duration': 2 * 60 + 30, 'due': time_to_continuous_minutes('Wednesday', 8, 45), 'weight': 4},
}
MACHINES = ['A', 'B', 'C']
SPT¶
order=sorted(JOBS, key=lambda x: (JOBS[x]['duration'], x))
gantt(JOBS, schedule(JOBS,order))
kpi(JOBS, schedule(JOBS,order))
# SPT
print("\nEDD Order:")
print_job_order(JOBS, order)
kpi(JOBS, SCHEDULE)
EDD Order:
| Job | Start (min) | Duration (min) | Due (min) | Weight | |
|---|---|---|---|---|---|
| 0 | 13 | 450 | 45 | 1125 | 1 |
| 1 | 15 | 900 | 60 | 1065 | 3 |
| 2 | 12 | 465 | 75 | 1020 | 1 |
| 3 | 8 | 1185 | 75 | 2505 | 1 |
| 4 | 7 | 1110 | 90 | 1530 | 3 |
| 5 | 2 | 465 | 105 | 1440 | 3 |
| 6 | 4 | 30 | 120 | 1545 | 1 |
| 7 | 14 | 90 | 135 | 930 | 1 |
| 8 | 17 | 450 | 150 | 1245 | 4 |
| 9 | 5 | 150 | 150 | 630 | 1 |
| 10 | 1 | 1125 | 165 | 1350 | 1 |
| 11 | 16 | 1140 | 165 | 2940 | 4 |
| 12 | 3 | 585 | 165 | 2025 | 4 |
| 13 | 10 | 555 | 180 | 1470 | 1 |
| 14 | 9 | 330 | 180 | 2175 | 2 |
| 15 | 6 | 1080 | 195 | 2370 | 2 |
| 16 | 11 | 1065 | 225 | 2130 | 1 |
{'Makespan': 1785,
'Max Pastdue': 960,
'Sum of Pastdue': 1290,
'Number Pastdue': 4,
'Number on Time': 13,
'Fraction on Time': 0.7647058823529411}
EDD¶
order = sorted(JOBS, key=lambda x: (JOBS[x]['due'], x))
gantt(JOBS, schedule(JOBS,order))
kpi(JOBS, schedule(JOBS,order))
# EDD - Earliest Due Date first
print("\nEDD Order:")
print_job_order(JOBS, order)
kpi(JOBS, SCHEDULE)
EDD Order:
| Job | Start (min) | Duration (min) | Due (min) | Weight | |
|---|---|---|---|---|---|
| 0 | 5 | 150 | 150 | 630 | 1 |
| 1 | 14 | 90 | 135 | 930 | 1 |
| 2 | 12 | 465 | 75 | 1020 | 1 |
| 3 | 15 | 900 | 60 | 1065 | 3 |
| 4 | 13 | 450 | 45 | 1125 | 1 |
| 5 | 17 | 450 | 150 | 1245 | 4 |
| 6 | 1 | 1125 | 165 | 1350 | 1 |
| 7 | 2 | 465 | 105 | 1440 | 3 |
| 8 | 10 | 555 | 180 | 1470 | 1 |
| 9 | 7 | 1110 | 90 | 1530 | 3 |
| 10 | 4 | 30 | 120 | 1545 | 1 |
| 11 | 3 | 585 | 165 | 2025 | 4 |
| 12 | 11 | 1065 | 225 | 2130 | 1 |
| 13 | 9 | 330 | 180 | 2175 | 2 |
| 14 | 6 | 1080 | 195 | 2370 | 2 |
| 15 | 8 | 1185 | 75 | 2505 | 1 |
| 16 | 16 | 1140 | 165 | 2940 | 4 |
{'Makespan': 1785,
'Max Pastdue': 960,
'Sum of Pastdue': 1290,
'Number Pastdue': 4,
'Number on Time': 13,
'Fraction on Time': 0.7647058823529411}
3.2¶
Additionally, explore an alternative approach that could be used to achieve an optimal or near-optimal schedule, and explain the differences between the two.
def opt_schedule(JOBS):
# Create the mip solver with the SCIP backend.
m = pywraplp.Solver.CreateSolver('SCIP')
# upper bounds on how long it would take to process all jobs
tmax = max([JOBS[job_id]['release'] for job_id in JOBS.keys()]) + sum([JOBS[job_id]['duration'] for job_id in JOBS.keys()])
# decision variables
completion_time = []
auxilaryVar = []
for job in range(len(JOBS.keys())):
suffix = '_%s' % job
completion_time.append(m.NumVar(0, tmax, 'complete' + suffix))
auxilaryVar_nested=[]
for job_k in JOBS.keys():
auxilaryVar_nested.append(m.BoolVar('y' + suffix))
auxilaryVar.append(auxilaryVar_nested)
# additional decision variables for use in the objecive
maxpastdue = m.NumVar(-tmax, tmax, 'maxpastdue')
# constraints
for j,job_id in enumerate(JOBS.keys()):
m.Add(completion_time[j] >= JOBS[job_id]['release'] + JOBS[job_id]['duration'])
m.Add(maxpastdue >= completion_time[j] - JOBS[job_id]['due'])
for k,job_id_k in enumerate(JOBS.keys()):
if k !=j:
m.Add(completion_time[j] + JOBS[job_id_k]['duration'] <= completion_time[k] + tmax*auxilaryVar[j][k])
m.Add(completion_time[k] + JOBS[job_id]['duration'] <= completion_time[j] + tmax*(1 - auxilaryVar[j][k]))
# objective function
m.Minimize(maxpastdue)
status = m.Solve()
if status == pywraplp.Solver.OPTIMAL:
print(maxpastdue.solution_value())
SCHEDULE = {}
for j,job_id in enumerate(JOBS.keys()):
SCHEDULE[job_id] = {'machine': 1, 'start': completion_time[j].solution_value() - JOBS[job_id]['duration'], 'finish': completion_time[j].solution_value()}
# print(SCHEDULE)
return SCHEDULE
else:
print('The problem does not have an optimal solution.')
SCHEDULE = opt_schedule(JOBS)
gantt(JOBS, SCHEDULE)
kpi(JOBS, SCHEDULE)
-60.00000000000001
{'Makespan': 2714.9999999999995,
'Max Pastdue': 0,
'Sum of Pastdue': 0,
'Number Pastdue': 0,
'Number on Time': 17,
'Fraction on Time': 1.0}
Number of delayed jobs¶
def opt_schedule(JOBS):
# Create the mip solver with the SCIP backend.
m = pywraplp.Solver.CreateSolver('SCIP')
# upper bounds on how long it would take to process all jobs
tmax = max([JOBS[job_id]['release'] for job_id in JOBS.keys()]) + sum([JOBS[job_id]['duration'] for job_id in JOBS.keys()])
# decision variables
completion_time = []
auxilaryVar = []
for job in range(len(JOBS.keys())):
suffix = '_%s' % job
completion_time.append(m.NumVar(0, tmax, 'complete' + suffix))
auxilaryVar_nested=[]
for job_k in JOBS.keys():
auxilaryVar_nested.append(m.BoolVar('y' + suffix))
auxilaryVar.append(auxilaryVar_nested)
# additional decision variables for use in the objecive
ispastdue = []
for job_id in JOBS.keys():
ispastdue.append(m.BoolVar('ispastdue'))
# constraints
for j,job_id in enumerate(JOBS.keys()):
m.Add(completion_time[j] <= JOBS[job_id]['due'] + tmax * ispastdue[j])
m.Add(completion_time[j] >= JOBS[job_id]['release'] + JOBS[job_id]['duration'])
for k,job_id_k in enumerate(JOBS.keys()):
if k !=j:
m.Add(completion_time[j] + JOBS[job_id_k]['duration'] <= completion_time[k] + tmax*auxilaryVar[j][k])
m.Add(completion_time[k] + JOBS[job_id]['duration'] <= completion_time[j] + tmax*(1 - auxilaryVar[j][k]))
# objective function
m.Minimize(sum(ispastdue))
status = m.Solve()
if status == pywraplp.Solver.OPTIMAL:
print(sum(ispastdue[job_id].solution_value() for job_id in range(len(JOBS.keys()))))
SCHEDULE = {}
for j,job_id in enumerate(JOBS.keys()):
SCHEDULE[job_id] = {'machine': 1, 'start': completion_time[j].solution_value() - JOBS[job_id]['duration'], 'finish': completion_time[j].solution_value()}
# print(SCHEDULE)
return SCHEDULE
else:
print('The problem does not have an optimal solution.')
SCHEDULE = opt_schedule(JOBS)
gantt(JOBS, SCHEDULE)
kpi(JOBS, SCHEDULE)
0.0
{'Makespan': 2939.9999999999995,
'Max Pastdue': 4.547473508864641e-13,
'Sum of Pastdue': 4.547473508864641e-13,
'Number Pastdue': 1,
'Number on Time': 16,
'Fraction on Time': 0.9411764705882353}
Moore and Hudson Algo¶
order = sorted(JOBS, key=lambda x: (JOBS[x]['due'], x))
# print(order)
Flow_Time = []
j = 0
while j < len(order):
job = order[j]
# print(j,job)
if len(Flow_Time) == 0:
Flow_Time.append(JOBS[job]['duration'])
else:
Flow_Time.append(Flow_Time[-1] + JOBS[job]['duration'])
# print(Flow_Time)
if Flow_Time[j] > JOBS[job]['due']:
remove_ele = np.argmax(np.array([JOBS[i]['duration'] for i in order[:j]]))
order.pop(remove_ele)
j = 0
Flow_Time = []
else:
j += 1
# print(order)
df = pd.DataFrame(np.column_stack((order,np.array([JOBS[job]['duration'] for job in order]),np.array([JOBS[job]['due'] for job in order]),Flow_Time)))
df.columns = ['Job','Processing Time','Due Date','Flow Time']
df.style
| Job | Processing Time | Due Date | Flow Time | |
|---|---|---|---|---|
| 0 | 5 | 150 | 630 | 150 |
| 1 | 14 | 135 | 930 | 285 |
| 2 | 12 | 75 | 1020 | 360 |
| 3 | 15 | 60 | 1065 | 420 |
| 4 | 13 | 45 | 1125 | 465 |
| 5 | 17 | 150 | 1245 | 615 |
| 6 | 1 | 165 | 1350 | 780 |
| 7 | 2 | 105 | 1440 | 885 |
| 8 | 10 | 180 | 1470 | 1065 |
| 9 | 7 | 90 | 1530 | 1155 |
| 10 | 4 | 120 | 1545 | 1275 |
| 11 | 3 | 165 | 2025 | 1440 |
| 12 | 11 | 225 | 2130 | 1665 |
| 13 | 9 | 180 | 2175 | 1845 |
| 14 | 6 | 195 | 2370 | 2040 |
| 15 | 8 | 75 | 2505 | 2115 |
| 16 | 16 | 165 | 2940 | 2280 |
3.3¶
Another way to address the urgency of producing certain products is by imposing deadlines for their delivery. Considering deadlines introduces various objectives, each with distinct implications for scheduling:
(a) Minimizing the overall delay from deadlines.
(b) Minimizing the maximum delay between deadlines and product completion time.
This could be due to the difficulty of storing some products as inventory.
(c) Minimizing the overall deviation of deadlines and product completion time.
(d) Minimizing the maximum deviation between deadlines and product completion time.
(e) Minimizing the number of products for which the deadline could not be accommodated.
Remember to prioritize tasks whenever possible!
- (a) used in q. 3.2 through number of tardy jobs
- (b) q.3.2 max lateness
- (c) ??
- (d) q.3.2 max lateness
- (e) q.3.2 moore hudson
Question 4¶
Constraint Analysis for Parallel-Machine Scheduling Model
Constraints Description¶
The constraints governing the scheduling of jobs on parallel machines can be described as follows:
Time Scheduling Constraint: $$ C_j + p_k \leq C_k + M(2 - x_{jm} - x_{km} + y_{jk}) \quad \forall j, k, m $$ This constraint ensures that if job (j) is scheduled before job (k) on any machine (m), then the completion time of job (j) plus the processing time of job (k) is less than or equal to the completion time of job (k), adjusted by a large constant (M) times the condition of sequencing and machine assignment.
Mutual Exclusivity Constraint: $$ C_k + p_j \leq C_j + M(3 - y_{jk} - x_{jm} - x_{km}) \quad \forall j, k, m $$ This ensures that two jobs cannot overlap in their scheduling unless the sequence and machine allocations are appropriately set.
Non-negativity Constraint: $$ C_j \geq 0 \quad \forall j $$ The completion times of all jobs must be non-negative.
Binary Constraint for Job Sequencing: $$ y_{jk} \in \{0, 1\} \quad \forall j, k $$ This binary variable indicates whether job (k) is processed after job (j).
Parameters and Variables¶
Processing time of job ( j ): $$ p_j $$
A large number (Big M): $$ M $$
Maximum completion time on all machines: $$ C_{\text{max}} $$
Completion time of job ( j ): $$ C_j $$
Binary variable, 1 if job ( k ) is processed after job ( j ) (job sequencing): $$ y_{jk} $$
Binary variable, 1 if job ( j ) is processed on machine ( m ) (machine assignment): $$ x_{jm} $$
Optimization Model¶
The objective is to minimize the maximum completion time across all machines: $$ \min C_{\text{max}} $$ subject to: $$ \sum_{j} x_{jm}p_j \leq C_{\text{max}} \quad \forall m $$ $$ \sum_{m} x_{jm} = 1 \quad \forall j $$ $$ x_{jm} \in \{0, 1\} \quad \forall j, m $$
Additional Constraints Needed¶
To complete the model, additional constraints are required to fully capture the scheduling problem:
Machine Capacity Constraint: Ensuring that each job is assigned to exactly one machine.
$$ \sum_{m} x_{jm} = 1 \quad \forall j $$
This ensures that each job ( j ) is assigned to exactly one machine ( m ).
Completion Time Constraint: Ensuring that the completion time of each job does not exceed the maximum completion time ( C_{\text{max}} ).
$$ \sum_{j} x_{jm} p_j \leq C_{\text{max}} \quad \forall m $$
This ensures that the total processing time on any machine ( m ) does not exceed ( C_{\text{max}} ).
Binary Assignment: Ensuring binary values for machine assignment variables.
$$ x_{jm} \in \{0, 1\} \quad \forall j, m $$
Integration of the Additional Constraints¶
When integrated with the given constraints, the model ensures proper scheduling of jobs on parallel machines while minimizing the makespan:
Objective:
$$ \min C_{\text{max}} $$
Constraints:
$$ C_j + p_k \leq C_k + M(2 - x_{jm} - x_{km} + y_{jk}) \quad \forall j, k, m $$
$$ C_k + p_j \leq C_j + M(3 - y_{jk} - x_{jm} - x_{km}) \quad \forall j, k, m $$
$$ C_j \geq 0 \quad \forall j $$
$$ y_{jk} \in \{0, 1\} \quad \forall j, k $$
$$ \sum_{m} x_{jm} = 1 \quad \forall j $$
$$ \sum_{j} x_{jm} p_j \leq C_{\text{max}} \quad \forall m $$
$$ x_{jm} \in \{0, 1\} \quad \forall j, m $$
Justification¶
Based on the course materials, these constraints form a comprehensive model for parallel machine scheduling aimed at minimizing the makespan. The additional constraints ensure that each job is processed exactly once and the load on each machine does not exceed the specified maximum completion time, ensuring an optimal schedule.
Course Reference¶
The constraints and methods align with the optimization models and heuristics for scheduling problems discussed in the course materials, particularly in sections focusing on multiple machines and minimizing the makespan:
- pages 165
Question 6¶
WoodCraft Creations has decided to incorporate an inspection booth after the assembly machines. They adhere to a full inspection policy to uphold the quality they promise. Full inspection involves examining every product or component to ensure it meets specific standards or requirements. At this station, an employee checks the products and assesses if they meet expectations. The file data project 2.csv provides the inspection time for each product.
Address this problem by taking into account the release time of each product at the completion of its assembly. Use the rules outlined below, ensuring that the priorities and deadlines align with those mentioned in the previous section:
- LPT
- SPT
- EDD
data_2 = pd.read_csv('data/data_project_2.csv')
data_2
| Needed_Time (Hour) | |
|---|---|
| 0 | 1.899808 |
| 1 | 0.590951 |
| 2 | 2.127029 |
| 3 | 2.889249 |
| 4 | 2.554759 |
| 5 | 0.058992 |
| 6 | 0.901546 |
| 7 | 1.275430 |
| 8 | 0.838140 |
| 9 | 1.912403 |
| 10 | 1.307950 |
| 11 | 0.942278 |
| 12 | 0.459693 |
| 13 | 2.124013 |
| 14 | 0.897701 |
| 15 | 1.870851 |
| 16 | 1.663483 |
# Convert inspection times to a list
inspection_times = [int(time * 60) for time in data_2['Needed_Time (Hour)']]
inspection_times
[113, 35, 127, 173, 153, 3, 54, 76, 50, 114, 78, 56, 27, 127, 53, 112, 99]
JOBS = {
'1': {'release': 1365, 'duration': 113, 'due': time_to_continuous_minutes('Wednesday', 10, 30), 'weight': 1},
'2': {'release': 570, 'duration': 35, 'due': time_to_continuous_minutes('Wednesday', 12, 0), 'weight': 3},
'3': {'release': 750, 'duration': 127, 'due': time_to_continuous_minutes('Thursday', 11, 45), 'weight': 4},
'4': {'release': 150, 'duration': 173, 'due': time_to_continuous_minutes('Wednesday', 13, 45), 'weight': 1},
'5': {'release': 375, 'duration': 153, 'due': time_to_continuous_minutes('Tuesday', 8, 30), 'weight': 1},
'6': {'release': 1275, 'duration': 3, 'due': time_to_continuous_minutes('Thursday', 17, 30), 'weight': 2},
'7': {'release': 1200, 'duration': 54, 'due': time_to_continuous_minutes('Wednesday', 13, 30), 'weight': 3},
'8': {'release': 1365, 'duration': 76, 'due': time_to_continuous_minutes('Friday', 9, 45), 'weight': 1},
'9': {'release': 1035, 'duration': 50, 'due': time_to_continuous_minutes('Thursday', 14, 15), 'weight': 2},
'10': {'release': 735, 'duration': 114, 'due': time_to_continuous_minutes('Wednesday', 12, 30), 'weight': 1},
'11': {'release': 1290, 'duration': 78, 'due': time_to_continuous_minutes('Thursday', 13, 30), 'weight': 1},
'12': {'release': 540, 'duration': 56, 'due': time_to_continuous_minutes('Tuesday', 15, 0), 'weight': 1},
'13': {'release': 1080, 'duration': 27, 'due': time_to_continuous_minutes('Tuesday', 16, 45), 'weight': 1},
'14': {'release': 225, 'duration': 127, 'due': time_to_continuous_minutes('Tuesday', 13, 30), 'weight': 1},
'15': {'release': 960, 'duration': 53, 'due': time_to_continuous_minutes('Tuesday', 15, 45), 'weight': 3},
'16': {'release': 1440, 'duration': 112, 'due': time_to_continuous_minutes('Friday', 17, 0), 'weight': 4},
'17': {'release': 600, 'duration': 99, 'due': time_to_continuous_minutes('Wednesday', 8, 45), 'weight': 4},
}
MACHINES = ['I']
LPT¶
def schedule(JOBS, order=sorted(JOBS.keys())):
"Schedule a dictionary of JOBS on a single machine in a specified order."
start = 0
finish = 0
SCHEDULE = {}
for job in order:
start = max(JOBS[job]['release'], finish)
finish = start + JOBS[job]['duration']
SCHEDULE[job] = {'start': start, 'finish': finish}
return SCHEDULE
SCHEDULE = schedule(JOBS)
SCHEDULE
order=sorted(JOBS,reverse = True, key=lambda x: (JOBS[x]['duration'], x))
print("LPT Order:")
print_job_order(JOBS, order)
gantt(JOBS, schedule(JOBS,order))
kpi(JOBS, schedule(JOBS,order))
LPT Order:
| Job | Start (min) | Duration (min) | Due (min) | Weight | |
|---|---|---|---|---|---|
| 0 | 4 | 150 | 173 | 1545 | 1 |
| 1 | 5 | 375 | 153 | 630 | 1 |
| 2 | 3 | 750 | 127 | 2025 | 4 |
| 3 | 14 | 225 | 127 | 930 | 1 |
| 4 | 10 | 735 | 114 | 1470 | 1 |
| 5 | 1 | 1365 | 113 | 1350 | 1 |
| 6 | 16 | 1440 | 112 | 2940 | 4 |
| 7 | 17 | 600 | 99 | 1245 | 4 |
| 8 | 11 | 1290 | 78 | 2130 | 1 |
| 9 | 8 | 1365 | 76 | 2505 | 1 |
| 10 | 12 | 540 | 56 | 1020 | 1 |
| 11 | 7 | 1200 | 54 | 1530 | 3 |
| 12 | 15 | 960 | 53 | 1065 | 3 |
| 13 | 9 | 1035 | 50 | 2175 | 2 |
| 14 | 2 | 570 | 35 | 1440 | 3 |
| 15 | 13 | 1080 | 27 | 1125 | 1 |
| 16 | 6 | 1275 | 3 | 2370 | 2 |
{'Makespan': 2121,
'Max Pastdue': 993,
'Sum of Pastdue': 4533,
'Number Pastdue': 8,
'Number on Time': 9,
'Fraction on Time': 0.5294117647058824}
SPT¶
order=sorted(JOBS, key=lambda x: (JOBS[x]['duration'], x))
gantt(JOBS, schedule(JOBS,order))
kpi(JOBS, schedule(JOBS,order))
# SPT
print("\nEDD Order:")
print_job_order(JOBS, order)
kpi(JOBS, SCHEDULE)
EDD Order:
| Job | Start (min) | Duration (min) | Due (min) | Weight | |
|---|---|---|---|---|---|
| 0 | 6 | 1275 | 3 | 2370 | 2 |
| 1 | 13 | 1080 | 27 | 1125 | 1 |
| 2 | 2 | 570 | 35 | 1440 | 3 |
| 3 | 9 | 1035 | 50 | 2175 | 2 |
| 4 | 15 | 960 | 53 | 1065 | 3 |
| 5 | 7 | 1200 | 54 | 1530 | 3 |
| 6 | 12 | 540 | 56 | 1020 | 1 |
| 7 | 8 | 1365 | 76 | 2505 | 1 |
| 8 | 11 | 1290 | 78 | 2130 | 1 |
| 9 | 17 | 600 | 99 | 1245 | 4 |
| 10 | 16 | 1440 | 112 | 2940 | 4 |
| 11 | 1 | 1365 | 113 | 1350 | 1 |
| 12 | 10 | 735 | 114 | 1470 | 1 |
| 13 | 14 | 225 | 127 | 930 | 1 |
| 14 | 3 | 750 | 127 | 2025 | 4 |
| 15 | 5 | 375 | 153 | 630 | 1 |
| 16 | 4 | 150 | 173 | 1545 | 1 |
{'Makespan': 2815,
'Max Pastdue': 2002,
'Sum of Pastdue': 10581,
'Number Pastdue': 15,
'Number on Time': 2,
'Fraction on Time': 0.11764705882352941}
EDD¶
order = sorted(JOBS, key=lambda x: (JOBS[x]['due'], x))
gantt(JOBS, schedule(JOBS,order))
kpi(JOBS, schedule(JOBS,order))
# EDD - Earliest Due Date first
print("\nEDD Order:")
print_job_order(JOBS, order)
kpi(JOBS, SCHEDULE)
EDD Order:
| Job | Start (min) | Duration (min) | Due (min) | Weight | |
|---|---|---|---|---|---|
| 0 | 5 | 375 | 153 | 630 | 1 |
| 1 | 14 | 225 | 127 | 930 | 1 |
| 2 | 12 | 540 | 56 | 1020 | 1 |
| 3 | 15 | 960 | 53 | 1065 | 3 |
| 4 | 13 | 1080 | 27 | 1125 | 1 |
| 5 | 17 | 600 | 99 | 1245 | 4 |
| 6 | 1 | 1365 | 113 | 1350 | 1 |
| 7 | 2 | 570 | 35 | 1440 | 3 |
| 8 | 10 | 735 | 114 | 1470 | 1 |
| 9 | 7 | 1200 | 54 | 1530 | 3 |
| 10 | 4 | 150 | 173 | 1545 | 1 |
| 11 | 3 | 750 | 127 | 2025 | 4 |
| 12 | 11 | 1290 | 78 | 2130 | 1 |
| 13 | 9 | 1035 | 50 | 2175 | 2 |
| 14 | 6 | 1275 | 3 | 2370 | 2 |
| 15 | 8 | 1365 | 76 | 2505 | 1 |
| 16 | 16 | 1440 | 112 | 2940 | 4 |
{'Makespan': 2815,
'Max Pastdue': 2002,
'Sum of Pastdue': 10581,
'Number Pastdue': 15,
'Number on Time': 2,
'Fraction on Time': 0.11764705882352941}
Question 7¶
Develop a MILP model designed to efficiently minimize the average completion time of the inspection station.
SCHEDULE = opt_schedule(JOBS)
gantt(JOBS, SCHEDULE)
kpi(JOBS, SCHEDULE)
1.0
{'Makespan': 2890.0,
'Max Pastdue': 1540.0,
'Sum of Pastdue': 1540.0,
'Number Pastdue': 1,
'Number on Time': 16,
'Fraction on Time': 0.9411764705882353}
Question 8¶
Assume that the inspection station is not ready for use for 15 minutes after the first job is completed for inspection. What would be the optimal results in this scenario? Are they different from the results achieved earlier? If so, how?
def milp_with_single_delay(JOBS, delay):
# Create the MIP solver with the SCIP backend.
solver = pywraplp.Solver.CreateSolver('SCIP')
if not solver:
return
# Big M value
BigM = 10000
# Decision variables
completion_time = {}
start_time = {}
y = {}
for job in JOBS:
completion_time[job] = solver.NumVar(0, BigM, f'completion_time_{job}')
start_time[job] = solver.NumVar(0, BigM, f'start_time_{job}')
for i in JOBS:
for j in JOBS:
if i != j:
y[(i, j)] = solver.BoolVar(f'y_{i}_{j}')
# Constraints
for job in JOBS:
solver.Add(start_time[job] >= JOBS[job]['release'])
solver.Add(completion_time[job] == start_time[job] + JOBS[job]['duration'])
for i in JOBS:
for j in JOBS:
if i != j:
if i == 'first_job':
solver.Add(start_time[i] + JOBS[i]['duration'] + delay <= start_time[j] + BigM * (1 - y[(i, j)]))
else:
solver.Add(start_time[i] + JOBS[i]['duration'] <= start_time[j] + BigM * (1 - y[(i, j)]))
solver.Add(start_time[j] + JOBS[j]['duration'] <= start_time[i] + BigM * y[(i, j)])
# Objective: Minimize the average completion time
solver.Minimize(solver.Sum([completion_time[job] for job in JOBS]) / len(JOBS))
# Solve
status = solver.Solve()
# Process solution
if status == pywraplp.Solver.OPTIMAL:
SCHEDULE = {}
for job in JOBS:
SCHEDULE[job] = {
'start': start_time[job].solution_value(),
'finish': completion_time[job].solution_value()
}
return SCHEDULE
else:
return None
# Mark the first job
first_job = '1'
# Run the model with a 15-minute delay after the first job
DELAY = 15
SCHEDULE_WITH_DELAY = milp_with_single_delay(JOBS, DELAY)
gantt(JOBS, SCHEDULE_WITH_DELAY)
kpi(JOBS, SCHEDULE)
{'Makespan': 2890.0,
'Max Pastdue': 1540.0,
'Sum of Pastdue': 1540.0,
'Number Pastdue': 1,
'Number on Time': 16,
'Fraction on Time': 0.9411764705882353}
WoodCraft Creations has a line dedicated to home accessories. Among their offerings are various types of rugs, including standard designs in two variations: black-and-white and colored. In line with their sustainability program, they’ve introduced a new line featuring natural-fiber rugs. These rugs are typically produced based on a make-to-stock policy. The specific production stages for each product are outlined in Table 8. The table also provides the corresponding processing times for each product at each stage.
Table 8: Processing Time of Each Item of Different Types on Different Machines
| Product | Fiber Processing | Coloring | Weaving | Inspection |
|---|---|---|---|---|
| Natural-Fiber Rug | 1.0 | 5.0 | 4.0 | 1.5 |
| Black & White Rug | - | - | 4.5 | 1.0 |
| Colored Rug | - | 3.0 | 5.0 | 1.5 |
WoodCraft Creations produces all the products in batches, and batch plans can operate under different storage policies. In this particular case, we will consider the following two storage policies:
- Unlimited Intermediate Storage (UIS): The intermediate product can be stored indefinitely. There is enough storage capacity.
TASKS = {
('Natural-Fiber Rug', 'Fiber Processing'): {'dur': 1.0, 'prec': None},
('Natural-Fiber Rug', 'Coloring'): {'dur': 5.0, 'prec': ('Natural-Fiber Rug', 'Fiber Processing')},
('Natural-Fiber Rug', 'Weaving'): {'dur': 4.0, 'prec': ('Natural-Fiber Rug', 'Coloring')},
('Natural-Fiber Rug', 'Inspection'): {'dur': 1.5, 'prec': ('Natural-Fiber Rug', 'Weaving')},
('Black & White Rug', 'Weaving'): {'dur': 4.5, 'prec': None},
('Black & White Rug', 'Inspection'): {'dur': 1.0, 'prec': ('Black & White Rug', 'Weaving')},
('Colored Rug', 'Coloring'): {'dur': 3.0, 'prec': None},
('Colored Rug', 'Weaving'): {'dur': 5.0, 'prec': ('Colored Rug', 'Coloring')},
('Colored Rug', 'Inspection'): {'dur': 1.5, 'prec': ('Colored Rug', 'Weaving')}
}
TASKS
def visualize(results):
schedule = pd.DataFrame(results)
JOBS = sorted(list(schedule['Job'].unique()))
MACHINES = sorted(list(schedule['Machine'].unique()))
makespan = schedule['Finish'].max()
bar_style = {'alpha':1.0, 'lw':25, 'solid_capstyle':'butt'}
text_style = {'color':'black', 'weight':'bold', 'ha':'center', 'va':'center', 'rotation': 20}
colors = mpl.cm.Dark2.colors
schedule.sort_values(by=['Job', 'Start'])
schedule.set_index(['Job', 'Machine'], inplace=True)
fig, ax = plt.subplots(2,1, figsize=(12, 5+(len(JOBS)+len(MACHINES))/4))
for jdx, j in enumerate(JOBS, 1):
for mdx, m in enumerate(MACHINES, 1):
if (j,m) in schedule.index:
xs = schedule.loc[(j,m), 'Start']
xf = schedule.loc[(j,m), 'Finish']
ax[0].plot([xs, xf], [jdx]*2, c=colors[mdx%7], **bar_style)
ax[0].text((xs + xf)/2, jdx, m, **text_style)
ax[1].plot([xs, xf], [mdx]*2, c=colors[jdx%7], **bar_style)
ax[1].text((xs + xf)/2, mdx, j, **text_style)
ax[0].set_title('Job Schedule')
ax[0].set_ylabel('Job')
ax[1].set_title('Machine Schedule')
ax[1].set_ylabel('Machine')
for idx, s in enumerate([JOBS, MACHINES]):
ax[idx].set_ylim(0.5, len(s) + 0.5)
ax[idx].set_yticks(range(1, 1 + len(s)))
ax[idx].set_yticklabels(s)
ax[idx].text(makespan, ax[idx].get_ylim()[0]-0.2, "{0:0.1f}".format(makespan), ha='center', va='top')
ax[idx].plot([makespan]*2, ax[idx].get_ylim(), 'r--')
ax[idx].set_xlabel('Time')
ax[idx].grid(True)
fig.tight_layout()
# visualize(results)
def jobshop_model(TASKS):
# Create the mip solver with the SCIP backend.
m = pywraplp.Solver.CreateSolver('SCIP')
# Define Sets
JOBS = [j for (j,m) in TASKS] #check
MACHINES = [m for (j,m) in TASKS.keys()]
# establish an upper bound on makespan
ub = sum(TASKS[t]['dur'] for t in TASKS.keys())
# decision variables
start = []
auxilaryVar = []
for t in TASKS.keys():
suffix = '_%s' % str(t)
start.append(m.NumVar(0, ub, 'start'))
auxilaryVar_nested = []
for tp in TASKS.keys():
suffix = '_%s' % str(t)
auxilaryVar_nested.append(m.BoolVar('z' ))
auxilaryVar.append(auxilaryVar_nested)
# additional decision variables for use in the objecive
makespan = m.NumVar(0, ub, 'makespan')
# constraints
for t,task in enumerate(TASKS.keys()):
m.Add(start[t] + TASKS[task]['dur'] <= makespan)
for tp,taskp in enumerate(TASKS.keys()):
if task == TASKS[taskp]['prec']:
m.Add(start[t] + TASKS[task]['dur'] <= start[tp])
if task[1] == taskp[1] and t < tp: #same machine
m.Add(start[t] + TASKS[task]['dur'] <= start[tp] + ub * auxilaryVar[t][tp])
m.Add(start[tp] + TASKS[taskp]['dur'] <= start[t] + ub * (1-auxilaryVar[t][tp]))
# objective function
m.Minimize(makespan)
status = m.Solve()
if status == pywraplp.Solver.OPTIMAL:
results = [{'Job': task[0],
'Machine': task[1],
'Start': start[t].solution_value(),
'Duration': TASKS[task]['dur'],
'Finish': start[t].solution_value() + TASKS[task]['dur']}
for t,task in enumerate(TASKS.keys())]
results = []
for t,task in enumerate(TASKS.keys()):
results.append({'Job': task[0],
'Machine': task[1],
'Start': start[t].solution_value(),
'Duration': TASKS[task]['dur'],
'Finish': start[t].solution_value() + TASKS[task]['dur']})
return results
else:
print('The problem does not have an optimal solution.')
results = jobshop_model(TASKS)
visualize(results)
- Zero-Wait (ZW): The material cannot wait between different processes and must be processed as soon as it is produced.
def jobshop_model_zero_wait(TASKS):
# Create the mip solver with the SCIP backend.
m = pywraplp.Solver.CreateSolver('SCIP')
if not m:
return
# Define Sets
JOBS = list(set(j for (j, _) in TASKS))
MACHINES = list(set(m for (_, m) in TASKS.keys()))
# Establish an upper bound on makespan
ub = sum(TASKS[t]['dur'] for t in TASKS.keys())
# Decision variables
start = {}
auxilaryVar = {}
for t in TASKS.keys():
start[t] = m.NumVar(0, ub, f'start_{t}')
for tp in TASKS.keys():
if t != tp:
auxilaryVar[(t, tp)] = m.BoolVar(f'aux_{t}_{tp}')
# Additional decision variables for use in the objective
makespan = m.NumVar(0, ub, 'makespan')
# Constraints
for t in TASKS.keys():
m.Add(start[t] + TASKS[t]['dur'] <= makespan)
if TASKS[t]['prec'] is not None:
# Zero-wait constraint: start the next task immediately after the previous task ends
m.Add(start[t] == start[TASKS[t]['prec']] + TASKS[TASKS[t]['prec']]['dur'])
for t, tp in auxilaryVar.keys():
if t[1] == tp[1]: # same machine
m.Add(start[t] + TASKS[t]['dur'] <= start[tp] + ub * auxilaryVar[(t, tp)])
m.Add(start[tp] + TASKS[tp]['dur'] <= start[t] + ub * (1 - auxilaryVar[(t, tp)]))
# Objective function
m.Minimize(makespan)
status = m.Solve()
if status == pywraplp.Solver.OPTIMAL:
results = [{'Job': t[0],
'Machine': t[1],
'Start': start[t].solution_value(),
'Duration': TASKS[t]['dur'],
'Finish': start[t].solution_value() + TASKS[t]['dur']}
for t in TASKS.keys()]
return results
else:
print('The problem does not have an optimal solution.')
return None
# Define tasks
TASKS = {
('Natural-Fiber Rug', 'Fiber Processing'): {'dur': 1.0, 'prec': None},
('Natural-Fiber Rug', 'Coloring'): {'dur': 5.0, 'prec': ('Natural-Fiber Rug', 'Fiber Processing')},
('Natural-Fiber Rug', 'Weaving'): {'dur': 4.0, 'prec': ('Natural-Fiber Rug', 'Coloring')},
('Natural-Fiber Rug', 'Inspection'): {'dur': 1.5, 'prec': ('Natural-Fiber Rug', 'Weaving')},
('Black & White Rug', 'Weaving'): {'dur': 4.5, 'prec': None},
('Black & White Rug', 'Inspection'): {'dur': 1.0, 'prec': ('Black & White Rug', 'Weaving')},
('Colored Rug', 'Coloring'): {'dur': 3.0, 'prec': None},
('Colored Rug', 'Weaving'): {'dur': 5.0, 'prec': ('Colored Rug', 'Coloring')},
('Colored Rug', 'Inspection'): {'dur': 1.5, 'prec': ('Colored Rug', 'Weaving')}
}
# Run the model with zero-wait constraint
results = jobshop_model_zero_wait(TASKS)
visualize(results)
Question 9¶
Consider that WoodCraft Creations needs to deliver a batch of ”NNBBCC” rugs (two batches of natural-fiber rug, two batches of black&white rug and two batches of colored rug ) to the retail store. What would be the earliest time to deliver this order from the starting time?
TASKS = {
# Natural-Fiber Rug Batches
('Natural-Fiber Rug Batch 1', 'Fiber Processing'): {'dur': 1.0, 'prec': None},
('Natural-Fiber Rug Batch 1', 'Coloring'): {'dur': 5.0, 'prec': ('Natural-Fiber Rug Batch 1', 'Fiber Processing')},
('Natural-Fiber Rug Batch 1', 'Weaving'): {'dur': 4.0, 'prec': ('Natural-Fiber Rug Batch 1', 'Coloring')},
('Natural-Fiber Rug Batch 1', 'Inspection'): {'dur': 1.5, 'prec': ('Natural-Fiber Rug Batch 1', 'Weaving')},
('Natural-Fiber Rug Batch 2', 'Fiber Processing'): {'dur': 1.0, 'prec': None},
('Natural-Fiber Rug Batch 2', 'Coloring'): {'dur': 5.0, 'prec': ('Natural-Fiber Rug Batch 2', 'Fiber Processing')},
('Natural-Fiber Rug Batch 2', 'Weaving'): {'dur': 4.0, 'prec': ('Natural-Fiber Rug Batch 2', 'Coloring')},
('Natural-Fiber Rug Batch 2', 'Inspection'): {'dur': 1.5, 'prec': ('Natural-Fiber Rug Batch 2', 'Weaving')},
# Black & White Rug Batches
('Black & White Rug Batch 1', 'Weaving'): {'dur': 4.5, 'prec': None},
('Black & White Rug Batch 1', 'Inspection'): {'dur': 1.0, 'prec': ('Black & White Rug Batch 1', 'Weaving')},
('Black & White Rug Batch 2', 'Weaving'): {'dur': 4.5, 'prec': None},
('Black & White Rug Batch 2', 'Inspection'): {'dur': 1.0, 'prec': ('Black & White Rug Batch 2', 'Weaving')},
# Colored Rug Batches
('Colored Rug Batch 1', 'Coloring'): {'dur': 3.0, 'prec': None},
('Colored Rug Batch 1', 'Weaving'): {'dur': 5.0, 'prec': ('Colored Rug Batch 1', 'Coloring')},
('Colored Rug Batch 1', 'Inspection'): {'dur': 1.5, 'prec': ('Colored Rug Batch 1', 'Weaving')},
('Colored Rug Batch 2', 'Coloring'): {'dur': 3.0, 'prec': None},
('Colored Rug Batch 2', 'Weaving'): {'dur': 5.0, 'prec': ('Colored Rug Batch 2', 'Coloring')},
('Colored Rug Batch 2', 'Inspection'): {'dur': 1.5, 'prec': ('Colored Rug Batch 2', 'Weaving')},
}
results = jobshop_model_zero_wait(TASKS)
visualize(results)
# Find the makespan
makespan = max(result['Finish'] for result in results)
print(f"The earliest time to deliver the 'NNBBCC' order is: {makespan} hours from the starting time.")
The earliest time to deliver the 'NNBBCC' order is: 28.0 hours from the starting time.
If you consider the use of the ’UIS policy’, what is the final schedule after applying this policy ? How this schedule will differ from the simple summation of the processing times?
results = jobshop_model(TASKS)
visualize(results)
Question 10¶
Can you use the production planning model to answer the above question? If yes, give the answer with it. Justify your answers.
Question 11¶
Starting from the model in question 9, consider now that the fiber processing section is only available five time units after the process starts. How does it affect the result, and why?
def jobshop_model_with_fiber_delay(TASKS, fiber_delay):
# Create the mip solver with the SCIP backend.
m = pywraplp.Solver.CreateSolver('SCIP')
if not m:
return
# Define Sets
JOBS = list(set(j for (j, _) in TASKS))
MACHINES = list(set(m for (_, m) in TASKS.keys()))
# Establish an upper bound on makespan
ub = sum(TASKS[t]['dur'] for t in TASKS.keys())
# Decision variables
start = {}
auxilaryVar = {}
for t in TASKS.keys():
start[t] = m.NumVar(0, ub, f'start_{t}')
for tp in TASKS.keys():
if t != tp:
auxilaryVar[(t, tp)] = m.BoolVar(f'aux_{t}_{tp}')
# Additional decision variables for use in the objective
makespan = m.NumVar(0, ub, 'makespan')
# Constraints
for t in TASKS.keys():
m.Add(start[t] + TASKS[t]['dur'] <= makespan)
if TASKS[t]['prec'] is not None:
# Ensure the task starts after its predecessor ends
m.Add(start[t] >= start[TASKS[t]['prec']] + TASKS[TASKS[t]['prec']]['dur'])
for t, tp in auxilaryVar.keys():
if t[1] == tp[1]: # same machine
m.Add(start[t] + TASKS[t]['dur'] <= start[tp] + ub * auxilaryVar[(t, tp)])
m.Add(start[tp] + TASKS[tp]['dur'] <= start[t] + ub * (1 - auxilaryVar[(t, tp)]))
# Add fiber processing delay constraint
for t in TASKS.keys():
if t[1] == 'Fiber Processing':
m.Add(start[t] >= fiber_delay)
# Objective function
m.Minimize(makespan)
status = m.Solve()
if status == pywraplp.Solver.OPTIMAL:
results = [{'Job': t[0],
'Machine': t[1],
'Start': start[t].solution_value(),
'Duration': TASKS[t]['dur'],
'Finish': start[t].solution_value() + TASKS[t]['dur']}
for t in TASKS.keys()]
return results
else:
print('The problem does not have an optimal solution.')
return None
# Run the model with fiber processing delay
fiber_delay = 5 # Fiber processing section is available 5 time units after the process starts
results_fiber_delay = jobshop_model_with_fiber_delay(TASKS, fiber_delay)
visualize(results_fiber_delay)
# Find the makespan
makespan_fiber_delay = max(result['Finish'] for result in results_fiber_delay)
print(f"The makespan with fiber processing delay is: {makespan_fiber_delay} hours.")
The makespan with fiber processing delay is: 27.999999999999996 hours.
Question 12¶
In the stations, to consider specific protocols, they need to clean each section after producing one batch. So if natural-fiber rug is in the inspection station, they must do some cleaning, unless the next batch is again natural-fiber rug. Consider a cleaning time of one unit. Add this constraint to your model and report the result. Describe how it affects your previous solution and what the differences are.
CLEANING_TIME = 1.0 # Time unit for cleaning between different rug types
def jobshop_model_with_cleaning(TASKS, fiber_delay, cleaning_time):
# Create the mip solver with the SCIP backend.
m = pywraplp.Solver.CreateSolver('SCIP')
if not m:
return
# Define Sets
JOBS = list(set(j for (j, _) in TASKS))
MACHINES = list(set(m for (_, m) in TASKS.keys()))
# Establish an upper bound on makespan
ub = sum(TASKS[t]['dur'] for t in TASKS.keys()) + cleaning_time * (len(TASKS) - 1)
# Decision variables
start = {}
auxilaryVar = {}
for t in TASKS.keys():
start[t] = m.NumVar(0, ub, f'start_{t}')
for tp in TASKS.keys():
if t != tp:
auxilaryVar[(t, tp)] = m.BoolVar(f'aux_{t}_{tp}')
# Additional decision variables for use in the objective
makespan = m.NumVar(0, ub, 'makespan')
# Constraints
for t in TASKS.keys():
m.Add(start[t] + TASKS[t]['dur'] <= makespan)
if TASKS[t]['prec'] is not None:
# Ensure the task starts after its predecessor ends
m.Add(start[t] >= start[TASKS[t]['prec']] + TASKS[TASKS[t]['prec']]['dur'])
for t, tp in auxilaryVar.keys():
if t[1] == tp[1]: # same machine
if t[0].split()[0] != tp[0].split()[0]: # Different rug types require cleaning
m.Add(start[t] + TASKS[t]['dur'] + cleaning_time <= start[tp] + ub * auxilaryVar[(t, tp)])
else:
m.Add(start[t] + TASKS[t]['dur'] <= start[tp] + ub * auxilaryVar[(t, tp)])
m.Add(start[tp] + TASKS[tp]['dur'] <= start[t] + ub * (1 - auxilaryVar[(t, tp)]))
# Add fiber processing delay constraint
for t in TASKS.keys():
if t[1] == 'Fiber Processing':
m.Add(start[t] >= fiber_delay)
# Objective function
m.Minimize(makespan)
status = m.Solve()
if status == pywraplp.Solver.OPTIMAL:
results = [{'Job': t[0],
'Machine': t[1],
'Start': start[t].solution_value(),
'Duration': TASKS[t]['dur'],
'Finish': start[t].solution_value() + TASKS[t]['dur']}
for t in TASKS.keys()]
return results
else:
print('The problem does not have an optimal solution.')
return None
# Run the model with cleaning time constraint
fiber_delay = 5 # Fiber processing section is available 5 time units after the process starts
cleaning_time = 1.0 # Time unit for cleaning between different rug types
results_with_cleaning = jobshop_model_with_cleaning(TASKS, fiber_delay, cleaning_time)
visualize(results_with_cleaning)
# Find the makespan
makespan_with_cleaning = max(result['Finish'] for result in results_with_cleaning)
print(f"The makespan with cleaning time constraint is: {makespan_with_cleaning} hours.")
The makespan with cleaning time constraint is: 30.499999999999996 hours.
# Calculate the difference
difference_cleaning = makespan_with_cleaning - makespan_fiber_delay
print(f"Difference between fiber delay makespan and makespan with cleaning time constraint: {difference_cleaning} hours.")
Difference between fiber delay makespan and makespan with cleaning time constraint: 2.5 hours.
Question 13¶
Assume a Zero-wait policy that prevents the material from waiting between different processes. Add the corresponding constraint to your model and comment on the result.
def jobshop_model_with_cleaning_and_zero_wait(TASKS, fiber_delay, cleaning_time):
# Create the mip solver with the SCIP backend.
m = pywraplp.Solver.CreateSolver('SCIP')
if not m:
return
# Define Sets
JOBS = list(set(j for (j, _) in TASKS))
MACHINES = list(set(m for (_, m) in TASKS.keys()))
# Establish an upper bound on makespan
ub = sum(TASKS[t]['dur'] for t in TASKS.keys()) + cleaning_time * (len(TASKS) - 1)
# Decision variables
start = {}
auxilaryVar = {}
for t in TASKS.keys():
start[t] = m.NumVar(0, ub, f'start_{t}')
for tp in TASKS.keys():
if t != tp:
auxilaryVar[(t, tp)] = m.BoolVar(f'aux_{t}_{tp}')
# Additional decision variables for use in the objective
makespan = m.NumVar(0, ub, 'makespan')
# Constraints
for t in TASKS.keys():
m.Add(start[t] + TASKS[t]['dur'] <= makespan)
if TASKS[t]['prec'] is not None:
# Zero-wait constraint: Ensure the next task starts immediately after the current task ends
m.Add(start[t] == start[TASKS[t]['prec']] + TASKS[TASKS[t]['prec']]['dur'])
for t, tp in auxilaryVar.keys():
if t[1] == tp[1]: # same machine
if t[0].split()[0] != tp[0].split()[0]: # Different rug types require cleaning
m.Add(start[t] + TASKS[t]['dur'] + cleaning_time <= start[tp] + ub * auxilaryVar[(t, tp)])
else:
m.Add(start[t] + TASKS[t]['dur'] <= start[tp] + ub * auxilaryVar[(t, tp)])
m.Add(start[tp] + TASKS[tp]['dur'] <= start[t] + ub * (1 - auxilaryVar[(t, tp)]))
# Add fiber processing delay constraint
for t in TASKS.keys():
if t[1] == 'Fiber Processing':
m.Add(start[t] >= fiber_delay)
# Objective function
m.Minimize(makespan)
status = m.Solve()
if status == pywraplp.Solver.OPTIMAL:
results = [{'Job': t[0],
'Machine': t[1],
'Start': start[t].solution_value(),
'Duration': TASKS[t]['dur'],
'Finish': start[t].solution_value() + TASKS[t]['dur']}
for t in TASKS.keys()]
return results
else:
print('The problem does not have an optimal solution.')
return None
# Run the model with zero-wait, fiber delay, and cleaning time constraint
fiber_delay = 5 # Fiber processing section is available 5 time units after the process starts
cleaning_time = 1.0 # Time unit for cleaning between different rug types
results_with_cleaning_and_zero_wait = jobshop_model_with_cleaning_and_zero_wait(TASKS, fiber_delay, cleaning_time)
visualize(results_with_cleaning_and_zero_wait)
# Find the makespan
makespan_with_cleaning_and_zero_wait = max(result['Finish'] for result in results_with_cleaning_and_zero_wait)
print(f"The makespan with zero-wait, cleaning time, and fiber processing delay is: {makespan_with_cleaning_and_zero_wait} hours.")
The makespan with zero-wait, cleaning time, and fiber processing delay is: 31.5 hours.